Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/ThrowHelper.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/ThrowHelper.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/ThrowHelper.cs (revision 330) @@ -0,0 +1,281 @@ +// 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.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Resources; +using Deltares.DamEngine.Data.General; + +namespace Deltares.DamEngine.Calculators.General +{ + /// + /// Declares the string resource names + /// + internal enum StringResourceNames + { + CsvFileNotFound, + CsvFileNotValid, + CsvHeaderEmptyOrNull, + CsvHeaderNotValid, + CsvObjectMaterializerNotValid, + CsvSplitterPatternNotValid, + DataImportArgumentNull, + EntityAlreadyExist, + EntityFactoryArgumentNull, + ImportFileNotExist, + ImportFolderNotExist, + ImportFolderNullOrEmpty, + MStabExecutableFileNameNotFound, + SlopeWExecutableFileNameNotFound, + OutputFileNotExist, + OutputFileHasNoContent, + OutputFileNameNotValid, + ProjectFileNameNullOrEmpty, + ProjectFileNotExist, + SegmentIdArgumentNullOrEmpty, + SoilProfileIdArgumentNullOrEmpty, + SurfaceLineIdArgumentNullOrEmpty, + RequiredEntityDoesNotExist, + ImportFilesNotValidated, + RequiredParameterMissing, + SurfacelineIsNotInsideSoilprofile, + TopLayerToBeEvaluatedNotInsideSoilprofile, + SoilAttachedToLayerNotValid, + ImportDataNotValid, + ImportedLocationDoesntHaveValidSurfaceLines, + ImportedLocationDoesntHaveValidPL1Lines, + SurfaceLinePointNotExtists, + NonExistentLocation, + TwoSandlayersRequiredInSoilProfile, + CsvColumnIndexAlreadyExists, + WaterLevelInputFileNullOrEmpty, + NoSoilProfileDefinedForLocation, + LocationHasNoSegment, + FileNameNotValid, + GaugeIdArgumentNullOrEmpty, + LocationIdArgumentNullOrEmpty, + ImportedLocationDoesntHaveSoilprofile, + SoildatabaseNotFound, + SurfaceLineNotAssigned, + SoilProfileNotAssigned, + SoilListIsNull, + PL1NotCreated, + NonWaterRetainingObjectCategoryArgumentNullOrEmpty, + NonWaterRetainingObjectTypeArgumentNullOrEmpty + } + + /// + /// Defines a helper class for getting string resources + /// + /// + /// The class implements a singleton pattern + /// + internal class StringResources + { + /// + /// Holds a single reference to this class + /// + private static StringResources instance; + + /// + /// The sync method for making this class thread safe + /// + private static readonly object sync = new object(); + + /// + /// The actual resource manager + /// + private readonly ResourceManager resources; + + // Methods + internal StringResources() + { + this.resources = new ResourceManager("Deltares.Dam.Data.Properties.Resources", Assembly.GetExecutingAssembly()); + } + + /// + /// Gets the sinlgeton instance + /// + /// A reference to this class instance + private static StringResources GetInstance() + { + if (instance == null) + { + lock (sync) + { + if (instance == null) + { + instance = new StringResources(); + } + } + } + return instance; + } + + /// + /// Getst the string from the from the resource manager + /// + /// The name of the resource + /// The resource string + public static string GetString(string name) + { + var loader = GetInstance(); + if (loader == null) + { + return null; + } + return loader.resources.GetString(name, CultureInfo.CurrentCulture); + } + } + + /// + /// + /// + internal static class ThrowHelper + { + internal static string GetResourceString(StringResourceNames resourceNames) + { + return StringResources.GetString(resourceNames.ToString()); + } + + internal static void ThrowIfArgumentNull(object value, StringResourceNames resourceNamesName) + { + if (value == null) + throw new ArgumentNullException(StringResources.GetString(GetResourceString(resourceNamesName))); + } + + internal static void ThrowIfStringArgumentNullOrEmpty(string value, StringResourceNames resourceNamesName) + { + if (string.IsNullOrEmpty(value) || value.Trim() == "") + throw new ArgumentException(GetResourceString(resourceNamesName)); + } + + internal static void ThrowIfFileNameNullOrEmpty(string fileName) + { + ThrowIfFileNameNullOrEmpty(fileName, StringResourceNames.FileNameNotValid); + } + + internal static void ThrowIfFileNameNullOrEmpty(string fileName, StringResourceNames resourceName) + { + ThrowIfFileNameNullOrEmpty(fileName, resourceName); + } + + internal static void ThrowIfFileNameNullOrEmpty(string fileName, StringResourceNames resourceName) + where TException : Exception + { + ThrowWhenConditionIsTrue(resourceName, + () => string.IsNullOrEmpty(fileName) || fileName.Trim() == ""); + } + + internal static void ThrowIfFileNotExist(string fileName, StringResourceNames resourceNamesName) + { + if (!File.Exists(fileName)) + throw new FileNotFoundException(string.Format(GetResourceString(resourceNamesName), String.Format("{0} in {1}", (fileName ?? ""), DamProjectData.ProjectWorkingPath))); + } + + internal static void ThrowIfDirectoryNotExist(string dirName, StringResourceNames resourceNamesName) + { + if (!Directory.Exists(dirName)) + throw new DirectoryNotFoundException(string.Format(GetResourceString(resourceNamesName), dirName ?? "supplied")); + } + + internal static void ThrowWhenConditionIsTrue(Func condition, Func exceptionFactory) + where TException : Exception + { + if (condition()) + throw exceptionFactory(); + } + + public static void ThrowWhenConditionIsTrue(string message, Func condition) + where TException : Exception + { + var exception = (Exception)Activator.CreateInstance(typeof(TException), new object[] { message }); + + if (condition()) + throw exception; + } + + internal static void ThrowWhenConditionIsTrue(StringResourceNames resourceName, Func condition) + where TException : Exception + { + var exception = (Exception)Activator.CreateInstance( + typeof(TException), new object[] { GetResourceString(resourceName) }); + + if (condition()) + throw exception; + } + + internal static void ThrowWhenConditionIsTrue(TArgument arg, StringResourceNames resourceName, + Func condition, Func exceptionFactory) + where TException : Exception + { + var exception = exceptionFactory(resourceName); + if (condition(arg)) + throw exception; + } + + public static void ThrowWhenParameterIsMissing(object owner, string parameterName, object parameterValue) + { + if (parameterValue == null) + { + throw new ParameterMissingException( + string.Format(GetResourceString(StringResourceNames.RequiredParameterMissing), parameterName, owner.GetType().Name)); + } + } + + public static void ThrowWhenParameterIsMissing(object owner, string propertyName) + { + var pi = owner.GetType().GetProperty(propertyName); + var propertyValue = pi.GetValue(owner, null); + + if (propertyValue == null) + { + throw new ParameterMissingException( + string.Format(GetResourceString(StringResourceNames.RequiredParameterMissing), propertyName, owner.GetType().Name)); + } + } + + public static void ThrowWhenRequiredEntityDoesntExistInLookup(object id) where T : new() + { + throw new RequiredEntityNotExistException( + GetResourceString(StringResourceNames.RequiredEntityDoesNotExist), + typeof(T), + id); + } + + public static T ThrowWhenRequiredEntityDoesntExistInLookup(IEnumerable lookup, object id, Func predicate) where T : new() + { + var entity = lookup.FirstOrDefault(predicate); + if (Equals(entity, default(T))) + { + throw new RequiredEntityNotExistException( + GetResourceString(StringResourceNames.RequiredEntityDoesNotExist), + typeof(T), + id); + } + return entity; + } + } +} Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Soil.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Soil.cs (.../Soil.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Soil.cs (.../Soil.cs) (revision 330) @@ -38,6 +38,7 @@ private ShearStrengthModel shearStrengthModel = ShearStrengthModel.CPhi; private double belowPhreaticLevel = double.NaN; private double abovePhreaticLevel = double.NaN; + private double dryUnitWeight = double.NaN; private double cohesion = double.NaN; private double frictionAngle = double.NaN; private double poP = double.NaN; @@ -167,9 +168,31 @@ return abovePhreaticLevel; } } - + #endregion + #region property DryUnitWeight + + /// + /// Ovendry unit weight [kN/m3] + /// + public double DryUnitWeight + { + get + { + return dryUnitWeight; + } + set + { + if (!dryUnitWeight.Equals(value)) + { + dryUnitWeight = value; + } + } + } + + #endregion property DryUnitWeight + #region property Cohesion /// Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/StaticReflection.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/StaticReflection.cs (.../StaticReflection.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/StaticReflection.cs (.../StaticReflection.cs) (revision 330) @@ -42,7 +42,7 @@ return GetMemberName(expression); } - private static string GetMemberName(Expression> expression) + public static string GetMemberName(Expression> expression) { return GetMemberName(expression); } Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculatorException.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculatorException.cs (.../DAMFailureMechanismeCalculatorException.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculatorException.cs (.../DAMFailureMechanismeCalculatorException.cs) (revision 330) @@ -21,6 +21,7 @@ using System; using System.Runtime.Serialization; +using Deltares.DamEngine.Data.Design; namespace Deltares.DamEngine.Calculators { Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs =================================================================== diff -u -r316 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (.../SoilSurfaceProfile.cs) (revision 316) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (.../SoilSurfaceProfile.cs) (revision 330) @@ -398,7 +398,7 @@ aGeometry.Points.Add(topX); aGeometry.Points.Add(bottomX); aGeometry.Curves.Add(new GeometryCurve(topX, bottomX)); - aGeometry.NewlyEffectedCurves.Add(aGeometry.Curves.Last()); + //aGeometry.NewlyEffectedCurves.Add(aGeometry.Curves.Last());##Bka } private void BuildGeometryModel() @@ -436,65 +436,61 @@ { AddSettlementZones(Geometry); } - Geometry.NewlyEffectedPoints.AddRange(Geometry.Points); - Geometry.NewlyEffectedCurves.AddRange(Geometry.Curves); - Geometry.RegenerateGeometry(); - Geometry.DeleteLooseCurves(); +// Geometry.NewlyEffectedPoints.AddRange(Geometry.Points); +// Geometry.NewlyEffectedCurves.AddRange(Geometry.Curves); +// Geometry.RegenerateGeometry(); +// Geometry.DeleteLooseCurves();##Bka } private void RebuildSurfaces(GeometryData locGeometry) { - Surfaces.Clear(); - if (locGeometry == null || surfaceLine == null) - { - return; - } - var gu = new GeotechnicsUtilities(); - gu.RemoveGeometryDataAboveSurfaceLine(ref locGeometry, surfaceLine); - foreach (var geometrySurface in locGeometry.Surfaces) - { - var bounds = geometrySurface.GetGeometryBounds(); - var z = (bounds.Top + bounds.Bottom) * 0.5; - - var soilLayer = soilProfile.GetLayerAt(z); - - if (soilLayer != null) - { - Surfaces.Add(new SoilLayer2D - { - GeometrySurface = geometrySurface, - IsAquifer = soilLayer.IsAquifer, - WaterpressureInterpolationModel = soilLayer.WaterpressureInterpolationModel, - Soil = soilLayer.Soil, - SoilProfile = this - }); - } - } +// Surfaces.Clear(); +// if (locGeometry == null || surfaceLine == null) +// { +// return; +// } +// var gu = new GeotechnicsUtilities(); +// gu.RemoveGeometryDataAboveSurfaceLine(ref locGeometry, surfaceLine); +// foreach (var geometrySurface in locGeometry.Surfaces) +// { +// var bounds = geometrySurface.GetGeometryBounds(); +// var z = (bounds.Top + bounds.Bottom) * 0.5; +// +// var soilLayer = soilProfile.GetLayerAt(z); +// +// if (soilLayer != null) +// { +// Surfaces.Add(new SoilLayer2D +// { +// GeometrySurface = geometrySurface, +// IsAquifer = soilLayer.IsAquifer, +// WaterpressureInterpolationModel = soilLayer.WaterpressureInterpolationModel, +// Soil = soilLayer.Soil, +// SoilProfile = this +// }); +// } +// } ##Bka } /// /// Updates the layers. /// private void UpdateLayers() { - dirty = false; - initial = false; - - // Clear all cached soil profiles - cachedSoilProfiles1D.Clear(); - - DataEventPublisher.InvokeWithoutPublishingEvents(() => - { - if (orgSoilProfile != null) - { - soilProfile = (SoilProfile1D)orgSoilProfile.Clone(); - - UpdateDikeMaterial(); - BuildGeometryModel(); - RebuildSurfaces(Geometry); - } - }); - DataEventPublisher.DataListModified(Surfaces); +// dirty = false; +// initial = false; +// +// // Clear all cached soil profiles +// cachedSoilProfiles1D.Clear(); +// +// if (orgSoilProfile != null) +// { +// soilProfile = (SoilProfile1D)orgSoilProfile.Clone(); +// +// UpdateDikeMaterial(); +// BuildGeometryModel(); +// RebuildSurfaces(Geometry); +// } ##Bka } } } \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ConversionException.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ConversionException.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ConversionException.cs (revision 330) @@ -0,0 +1,45 @@ +// 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; + +namespace Deltares.DamEngine.Data.Standard +{ + public class ConversionException: Exception + { + private const string MessagePattern = "Couldn't convert '{0}' to type {1}"; + + public ConversionException() { } + + public ConversionException(Type type, object value) + : base(string.Format(MessagePattern, value, type.Name)) { } + + public ConversionException(Type type, object value, Exception inner) + : base(string.Format(MessagePattern, value, type.Name), inner) { } + + public ConversionException(string message, Exception inner) + : base(message, inner) { } + + protected ConversionException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } +} Index: dam engine/branches/Initial Source/Deltares.DamEngine.Controllers/Deltares.DamEngine.Controllers.csproj =================================================================== diff -u -r316 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Controllers/Deltares.DamEngine.Controllers.csproj (.../Deltares.DamEngine.Controllers.csproj) (revision 316) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Controllers/Deltares.DamEngine.Controllers.csproj (.../Deltares.DamEngine.Controllers.csproj) (revision 330) @@ -60,12 +60,13 @@ - - - + + {e943b1d5-fafa-4afe-9071-f8b22cf612ea} + Deltares.DamEngine.Calculators + {b7a49c1a-1c91-4d72-aba9-9fbac2509d8e} Deltares.DamEngine.Data Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityFileParseException.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityFileParseException.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityFileParseException.cs (revision 330) @@ -0,0 +1,49 @@ +// 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; + +namespace Deltares.DamEngine.Calculators.Stability +{ + [Serializable] + public class StabilityFileParseException : Exception + { + + public StabilityFileParseException() + { + } + + public StabilityFileParseException(string message) : base(message) + { + } + + public StabilityFileParseException(string message, Exception inner) : base(message, inner) + { + } + + protected StabilityFileParseException( + SerializationInfo info, + StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/SensorLocation.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/SensorLocation.cs (.../SensorLocation.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/SensorLocation.cs (.../SensorLocation.cs) (revision 330) @@ -313,35 +313,35 @@ /// /// Type of the pl line. /// - internal SortedDictionary GetSensorsSortedByRelativeLocationAlongProfile(PLLineType plLineType) - { - var calculatedRelativeLocations = BuildRelativeLocationTable(); +// internal SortedDictionary GetSensorsSortedByRelativeLocationAlongProfile(PLLineType plLineType) +// { +// var calculatedRelativeLocations = BuildRelativeLocationTable(); +// +// var table = new SortedDictionary(); +// +// // leave out the water level and polder level sensors +// var candidateSensors = +// Sensors.GetBySpecification(new PiezometricHeadSensorSpecification()); +// +// foreach (var sensor in candidateSensors) +// { +// if (sensor.PLLineMappings.Contains(plLineType)) +// { +// double relativeLocation = sensor.RelativeLocationSpecified ? +// sensor.RelativeLocation : calculatedRelativeLocations[sensor]; +// +// if (table.ContainsKey(relativeLocation)) +// { +// throw new InvalidOperationException( +// "Error creating lookup table with sensors sorted by relative location along profile. The x-location " + relativeLocation + " already exists. Sensor " + sensor); +// } +// +// table.Add(relativeLocation, sensor); +// } +// } +// return table; +// } ##Bka - var table = new SortedDictionary(); - - // leave out the water level and polder level sensors - var candidateSensors = - Sensors.GetBySpecification(new PiezometricHeadSensorSpecification()); - - foreach (var sensor in candidateSensors) - { - if (sensor.PLLineMappings.Contains(plLineType)) - { - double relativeLocation = sensor.RelativeLocationSpecified ? - sensor.RelativeLocation : calculatedRelativeLocations[sensor]; - - if (table.ContainsKey(relativeLocation)) - { - throw new InvalidOperationException( - "Error creating lookup table with sensors sorted by relative location along profile. The x-location " + relativeLocation + " already exists. Sensor " + sensor); - } - - table.Add(relativeLocation, sensor); - } - } - return table; - } - /// /// Builds the relative location table. /// @@ -365,7 +365,7 @@ internal static class MemberNames { - internal static readonly string OffsetBelowDikeToeAtPolder = StaticReflection.GetMemberName(this, x => x.PL1PLLineOffsetBelowDikeToeAtPolder); + internal static readonly string OffsetBelowDikeToeAtPolder = StaticReflection.GetMemberName(x => x.PL1PLLineOffsetBelowDikeToeAtPolder); internal static readonly string OffsetBelowDikeTopAtPolder = StaticReflection.GetMemberName(x => x.PL1PLLineOffsetBelowDikeTopAtPolder); internal static readonly string OffsetBelowDikeTopAtRiver = StaticReflection.GetMemberName(x => x.PL1PLLineOffsetBelowDikeTopAtRiver); internal static readonly string OffsetBelowShoulderBaseInside = StaticReflection.GetMemberName(x => x.PL1PLLineOffsetBelowShoulderBaseInside); Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/SoilGeometry.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/SoilGeometry.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/SoilGeometry.cs (revision 330) @@ -0,0 +1,91 @@ +// 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 Deltares.DamEngine.Data.Geotechnics; + +namespace Deltares.DamEngine.Data.General +{ + /// + /// Exception class for SoilGeometry + /// + public class SoilGeometryException : ApplicationException + { + public SoilGeometryException(string message) : base(message) + { + } + } + + public class SoilGeometryBase + { + public virtual SoilGeometryType SoilGeometryType { get; set; } + public virtual string SoilGeometryName { get; set; } + } + + /// + /// Super class to contain 1D and 2D soil geometry + /// + public class SoilGeometry : SoilGeometryBase + { + private SoilProfile1D soilProfile; + private string soilGeometry2DName; + + /// + /// Constructor + /// + public SoilGeometry(SoilProfile1D soilProfile, string soilGeometry2DName) + { + this.SoilProfile = soilProfile; + this.SoilGeometry2DName = soilGeometry2DName; + } + + #region PublicPropteries + public override SoilGeometryType SoilGeometryType + { + get + { + SoilGeometryType soilGeometryType = SoilGeometryType.SoilGeometry2D; + if (soilProfile != null) + { + soilGeometryType = SoilGeometryType.SoilGeometry1D; + } + if ((SoilProfile == null) && ((SoilGeometry2DName == null) || SoilGeometry2DName == "")) + { + throw new SoilGeometryException("No geometry assigned"); + } + return soilGeometryType; + } + } + + public SoilProfile1D SoilProfile + { + get { return soilProfile; } + set { soilProfile = value; } + } + + public string SoilGeometry2DName + { + get { return soilGeometry2DName; } + set { soilGeometry2DName = value; } + } + #endregion PublicPropteries + } +} Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/PlLinesCreator/PLLinesCreator.cs =================================================================== diff -u -r316 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/PlLinesCreator/PLLinesCreator.cs (.../Deltares.DamEngine.Controllers/PLLinesCreator.cs) (revision 316) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/PlLinesCreator/PLLinesCreator.cs (.../Deltares.DamEngine.Calculators/PlLinesCreator/PLLinesCreator.cs) (revision 330) @@ -23,14 +23,15 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using Deltares.DamEngine.Calculators.Uplift; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.Gauges; using Deltares.DamEngine.Data.General.PlLines; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard; -namespace Deltares.DamEngine.Controllers +namespace Deltares.DamEngine.Calculators.PlLinesCreator { [Serializable] public class PLLinesCreatorException : Exception @@ -69,7 +70,7 @@ public SoilProfile1D SoilProfile { get; set; } public string SoilGeometry2DName { get; set; } public Soil DikeEmbankmentMaterial { get; set; } - public SoilbaseDB SoilBaseDB { get; set; } + //public SoilbaseDB SoilBaseDB { get; set; } public SoilList SoilList { get; set; } public double? HeadInPLLine2 { get; set; } private double? headInPLLine3 { get; set; } @@ -135,7 +136,7 @@ // If hydraulic shortcut then use waterlevel for headPL3 if (IsHydraulicShortcut) { - if (SoilGeometryType == this.SoilGeometryType.SoilGeometry1D) + if (SoilGeometryType == SoilGeometryType.SoilGeometry1D) { if (SoilProfile.InBetweenAquiferLayer == null) { @@ -182,7 +183,7 @@ } } - private GeometryPointString currentPL1Line = null; // is needed when calculating uplift reduction for PL3 and Pl4 + private PLLine currentPL1Line = null; // is needed when calculating uplift reduction for PL3 and Pl4 // Output private double pl3MinUplift; @@ -204,7 +205,7 @@ /// public PLLinesCreator() { - SoilGeometryType = this.SoilGeometryType.SoilGeometry1D; + SoilGeometryType = SoilGeometryType.SoilGeometry1D; PlLineOffsetBelowDikeTopAtRiver = 0.5; // Default value PlLineOffsetBelowDikeTopAtPolder = 1.5; // Default value PlLineOffsetBelowShoulderBaseInside = 0.1; // Default value @@ -219,15 +220,15 @@ /// private SoilProfile1D GetSoilProfileBelowPoint(double xCoordinate) { - switch (this.SoilGeometryType) + switch (SoilGeometryType) { - case this.SoilGeometryType.SoilGeometry1D: + case SoilGeometryType.SoilGeometry1D: var soilProfile = new SoilProfile1D(); soilProfile.Assign(this.SoilProfile); return soilProfile; - case this.SoilGeometryType.SoilGeometry2D: - var geometry2DTo1DConverter = new Geometry2DTo1DConverter(this.SoilGeometry2DName, this.SurfaceLine, this.DikeEmbankmentMaterial, this.SoilBaseDB, this.SoilList, -this.XSoilGeometry2DOrigin); - return geometry2DTo1DConverter.Convert(xCoordinate); +// case SoilGeometryType.SoilGeometry2D: +// var geometry2DTo1DConverter = new Geometry2DTo1DConverter(this.SoilGeometry2DName, this.SurfaceLine, this.DikeEmbankmentMaterial, this.SoilBaseDB, this.SoilList, -this.XSoilGeometry2DOrigin); +// return geometry2DTo1DConverter.Convert(xCoordinate); ##Bka default: return null; } @@ -250,8 +251,8 @@ /// private void ThrowIfInsufficientSoilGeometryData() { - bool hasNoGeometry1DData = (SoilGeometryType == this.SoilGeometryType.SoilGeometry1D) && SoilProfile == null; - bool hasNoGeometry2DData = (SoilGeometryType == this.SoilGeometryType.SoilGeometry2D) && (SoilGeometry2DName == null || DikeEmbankmentMaterial == null || SoilBaseDB == null); + bool hasNoGeometry1DData = (SoilGeometryType == SoilGeometryType.SoilGeometry1D) && SoilProfile == null; + bool hasNoGeometry2DData = (SoilGeometryType == SoilGeometryType.SoilGeometry2D) && (SoilGeometry2DName == null || DikeEmbankmentMaterial == null); if (hasNoGeometry1DData && hasNoGeometry2DData) { throw new PLLinesCreatorException("PLLinesCreator contains not enough soil geometry information (SoilProfile, SoilGeometry2DName, dikeEmbankmentMaterial or soilBase)"); @@ -281,12 +282,12 @@ ThrowIfNoSurfaceLine(); ThrowIfSurfaceLineContainsNoPoints(); - switch (this.SoilGeometryType) + switch (SoilGeometryType) { - case this.SoilGeometryType.SoilGeometry1D: + case SoilGeometryType.SoilGeometry1D: plLine = CreatePlLine2ByExpertKnowledgeFor1DGeometry(penetrationLength, headInPLLine2); break; - case this.SoilGeometryType.SoilGeometry2D: + case SoilGeometryType.SoilGeometry2D: plLine = CreatePlLine2ByExpertKnowledgeFor2DGeometry(penetrationLength, headInPLLine2); break; } @@ -361,7 +362,7 @@ // Split layer at separation level var extraLayer = new SoilLayer1D(); extraLayer.Assign(separationLayer); - extraLayer.Id = this.SoilProfile.GetNewUniqueLayerId(); + //extraLayer.Id = this.SoilProfile.GetNewUniqueLayerId(); ##Bka extraLayer.TopLevel = separationLevel; this.SoilProfile.Layers.Insert(this.SoilProfile.Layers.IndexOf(separationLayer) + 1, extraLayer); } @@ -484,14 +485,14 @@ double headAtLastPlPoint = plLine.Points.Last().Z; double headAtEnd = plLine.Points.Last().Z - slopeGradient * lengthFromLastPlPointToEnd; - Line waterLevelPolderLine = - new Line(new GeometryPoint(this.surfaceLine.Geometry.Points.First().X, 0, this.WaterLevelPolder), - new GeometryPoint(this.surfaceLine.Geometry.Points.Last().X, 0, this.WaterLevelPolder)); - Line slopeLine = - new Line( - new GeometryPoint(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X, 0, headAtLastPlPoint), - new GeometryPoint(this.surfaceLine.Geometry.Points.Last().X, 0, headAtEnd)); - GeometryPoint intersectionPoint = new GeometryPoint(); + Line waterLevelPolderLine = + new Line(new Point2D(this.surfaceLine.Geometry.Points.First().X, this.WaterLevelPolder), + new Point2D(this.surfaceLine.Geometry.Points.Last().X, WaterLevelPolder)); + Line slopeLine = + new Line( + new Point2D(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X, headAtLastPlPoint), + new Point2D(this.surfaceLine.Geometry.Points.Last().X, headAtEnd)); + var intersectionPoint = new Point2D(); if (waterLevelPolderLine.IntersectsZ(slopeLine, out intersectionPoint)) { @@ -941,447 +942,447 @@ /// /// /// - private PLLines CreateAllPLLinesWithExpertKnowledge(Location location) - { - PLLines plLines = new PLLines(); - foreach (PLLineType plLineType in Enum.GetValues(typeof(PLLineType))) - { - bool isPL1LineDefinedForLocation = (location != null) && (location.LocalXZPL1Line != null) && (location.LocalXZPL1Line.Points.Count > 1); - if ((plLineType == PLLineType.PL1) && isPL1LineDefinedForLocation) - { - PLLine plLine = plLines.Lines[plLineType]; - CopyPointsInPLLine(ref plLine, location.LocalXZPL1Line); - } - else - { - plLines.Lines[plLineType] = CreatePLLineByExpertKnowledge(plLineType, location.DamType, location.SlopeDampingPiezometricHeightPolderSide); - } +// private PLLines CreateAllPLLinesWithExpertKnowledge(Location location) +// { +// PLLines plLines = new PLLines(); +// foreach (PLLineType plLineType in Enum.GetValues(typeof(PLLineType))) +// { +// bool isPL1LineDefinedForLocation = (location != null) && (location.LocalXZPL1Line != null) && (location.LocalXZPL1Line.Points.Count > 1); +// if ((plLineType == PLLineType.PL1) && isPL1LineDefinedForLocation) +// { +// PLLine plLine = plLines.Lines[plLineType]; +// CopyPointsInPLLine(ref plLine, location.LocalXZPL1Line); +// } +// else +// { +// plLines.Lines[plLineType] = CreatePLLineByExpertKnowledge(plLineType, location.DamType, location.SlopeDampingPiezometricHeightPolderSide); +// } +// +// // currentPL1Line is needed when calculating uplift reduction for PL3 and Pl4 +// if (plLineType == PLLineType.PL1) +// { +// // var plLine = plLines.Lines[plLineType]; +// // AdaptPL1ForNonWaterRetainingObject(ref plLine); +// // plLines.Lines[plLineType] = plLine; +// currentPL1Line = plLines.Lines[plLineType]; +// } +// } +// return plLines; +// } - // currentPL1Line is needed when calculating uplift reduction for PL3 and Pl4 - if (plLineType == PLLineType.PL1) - { - // var plLine = plLines.Lines[plLineType]; - // AdaptPL1ForNonWaterRetainingObject(ref plLine); - // plLines.Lines[plLineType] = plLine; - currentPL1Line = plLines.Lines[plLineType]; - } - } - return plLines; - } +// private IEnumerable FindAllPlLinePointsAtNWOLocation(PLLine pl1Line) +// { +// IEnumerable results = pl1Line.GetPointSegmentBetween(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).X - cOffsetPhreaticLineBelowSurface, +// this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).X + cOffsetPhreaticLineBelowSurface); +// +// return results; +// } - private IEnumerable FindAllPlLinePointsAtNWOLocation(PLLine pl1Line) - { - IEnumerable results = pl1Line.GetPointSegmentBetween(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).X - cOffsetPhreaticLineBelowSurface, - this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).X + cOffsetPhreaticLineBelowSurface); +// private void AdaptPL1ForNonWaterRetainingObject(ref PLLine pl1Line) +// { +// // check if nwo points are available as CharacteristicPoints +// var nwo1 = this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1); +// var nwo2 = this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint2); +// var nwo3 = this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint3); +// var nwo4 = this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4); +// if ((nwo1 != null) && (nwo2 != null) && (nwo3 != null) && (nwo4 != null)) +// { +// +// // Find all points in the Pl line that (might) coincide with the NWO +// IEnumerable plPointsToBeMoved = FindAllPlLinePointsAtNWOLocation(pl1Line); +// +// PLLinePoint nwo1Pl = null; +// PLLinePoint nwo2Pl = null; +// PLLinePoint nwo3Pl = null; +// PLLinePoint nwo4Pl = null; +// +// // For NWO point, determine whether a pl point has to be added +// if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo1) != PLLinePointPositionXzType.AbovePLLine) +// { +// nwo1Pl = new PLLinePoint(nwo1.X, nwo1.Z - cOffsetPhreaticLineBelowSurface); +// } +// if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo2) != PLLinePointPositionXzType.AbovePLLine) +// { +// nwo2Pl = new PLLinePoint(nwo2.X, nwo2.Z - cOffsetPhreaticLineBelowSurface); +// } +// if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo3) != PLLinePointPositionXzType.AbovePLLine) +// { +// nwo3Pl = new PLLinePoint(nwo3.X, nwo3.Z - cOffsetPhreaticLineBelowSurface); +// } +// if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo4) != PLLinePointPositionXzType.AbovePLLine) +// { +// nwo4Pl = new PLLinePoint(nwo4.X, nwo4.Z - cOffsetPhreaticLineBelowSurface); +// } +// +// // Find the intersections of pl line and NWO and handle these +// // Intersection between nwo point1 and nwo point2 only when nwo point1 is above pl line and nwo point2 is below plLine +// PLLinePoint intersection1 = null; +// if ((nwo1Pl == null) && (nwo2Pl != null)) +// { +// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, nwo1.Z), EndPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z) }; +// var ips = pl1Line.IntersectionPointsXzWithLineXz(lineNWO); +// if (ips.Count > 0) +// { +// intersection1 = new PLLinePoint(ips.First().X, ips.First().Z); +// } +// } +// // Intersection between nwo point3 and nwo point4 only when nwo point3 is below pl line and nwo point4 is above plLine +// PLLinePoint intersection2 = null; +// if ((nwo3Pl != null) && (nwo4Pl == null)) +// { +// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z), EndPoint = new GeometryPoint(nwo4.X, 0, nwo4.Z) }; +// var ips = pl1Line.IntersectionPointsXzWithLineXz(lineNWO); +// if (ips.Count > 0) +// { +// intersection2 = new PLLinePoint(ips.Last().X, ips.Last().Z); +// } +// } +// +// // Handle making the NWO empty +// if ((NWOPhreaticAdaption != null) && (NWOPhreaticAdaption == PhreaticAdaptionType.MakeEmpty)) +// { +// // for the polderside, the pl line is always allowed to be adapted. For the riverside, the pl line may only be adapted when the original waterlevel is runs through the nwo. +// RemoveAllWaterFromNonWaterRetainingObject(nwo1, pl1Line, nwo1Pl, nwo2Pl, nwo3Pl, nwo4Pl, intersection1, intersection2, plPointsToBeMoved); +// } +// // Handle making the waterlevel horizontal in the NWO at the Riverside when needed (Polderside is already done when needed, see CreatePhreaticLineSegmentsInShoulderAndPolder. +// if ((NWOPhreaticAdaption != null) && (NWOPhreaticAdaption == PhreaticAdaptionType.None)) +// { +// // For the riverside, the pl line may only be adapted when the original waterlevel is runs through the nwo and is not already level. +// if ((nwo1.X <= this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X) && ((intersection1 != null) || (intersection2 != null))) +// { +// double requiredWaterLevel; +// // Check whether adaption of intersection points is needed +// if (intersection2 == null) +// { +// // only intersection 1 avaialable so add intersection 2 +// // first see if nwo3/4 intersects, if not try nwo2/3. If still no intersection found valid level not possible, raise error +// MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1(nwo2, nwo3, nwo4, pl1Line, nwo3Pl, nwo4Pl, intersection1); +// requiredWaterLevel = intersection1.Z; +// } +// else +// { +// if (intersection1 == null) +// { +// // only intersection 2 avaialable so add intersection 1 +// // first see if nwo1/2 intersects, if not try nwo2/3. If still no intersection found valid level not possible, raise error +// MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2(nwo1, nwo2, nwo3, pl1Line, nwo1Pl, nwo2Pl, nwo3Pl, intersection2); +// requiredWaterLevel = intersection2.Z; +// } +// else +// { +// // intersection 1 and intersection 2 available. Only act when levels were different. +// requiredWaterLevel = Math.Min(intersection1.Z, intersection2.Z); +// if ((Math.Abs(intersection1.Z - intersection2.Z) > GeometryPoint.Precision)) +// { +// if (intersection1.Z < intersection2.Z) +// { +// // make level in NWO intersection1.Z +// MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1And2(nwo2, nwo3, nwo4, pl1Line, nwo3Pl, intersection1, intersection2); +// } +// else +// { +// // make level in NWO intersection2.Z +// MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2And1(nwo1, nwo2, nwo3, pl1Line, nwo2Pl, intersection1, intersection2); +// } +// +// } +// } +// } +// +// // Move all the points in the pl line itself that need to be moved to the horizontal proper level. +// foreach (var plLinePoint in plPointsToBeMoved) +// { +// plLinePoint.Z = requiredWaterLevel; +// } +// pl1Line.DeleteCoinsidingPoints(GeometryPoint.Precision); +// } +// } +// } +// } - return results; - } +// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2And1(GeometryPoint nwo1, GeometryPoint nwo2, GeometryPoint nwo3, PLLine pl1Line, PLLinePoint nwo2Pl, PLLinePoint intersection1, PLLinePoint intersection2) +// { +// var lineNWO = new Line { BeginPoint = new Point2D(nwo1.X, nwo1.Z), EndPoint = new Point2D(nwo2.X, nwo2.Z) }; +// var linePL = new Line { BeginPoint = new Point2D(nwo1.X, intersection2.Z), EndPoint = new Point2D(intersection2.X, intersection2.Z) }; +// var isp = new GeometryPoint(); +// if (LineHelper.GetStrictIntersectionPoint(lineNWO, linePL, ref isp)) +// { +// var newP1 = pl1Line.EnsurePointAtX(intersection2.X, GeometryPoint.Precision); +// newP1.Z = intersection2.Z; +// var newP2 = pl1Line.EnsurePointAtX(isp.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP2.Z = intersection2.Z; +// var newP3 = pl1Line.EnsurePointAtX(intersection1.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP3.Z = intersection1.Z; +// } +// else +// { +// var lineNWOb = new Line { BeginPoint = new Point2D(nwo2.X, nwo2.Z), EndPoint = new Point2D(nwo3.X, nwo3.Z) }; +// if (LineHelper.GetStrictIntersectionPoint(lineNWOb, linePL, ref isp)) +// { +// var newP1 = pl1Line.EnsurePointAtX(intersection2.X, GeometryPoint.Precision); +// newP1.Z = intersection2.Z; +// var newP2 = pl1Line.EnsurePointAtX(isp.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP2.Z = intersection2.Z; +// var newP3 = pl1Line.EnsurePointAtX(nwo2Pl.X, GeometryPoint.Precision); +// newP3.Z = nwo2Pl.Z; +// if (nwo2Pl.X > intersection1.X) +// { +// var newP4 = pl1Line.EnsurePointAtX(intersection1.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP4.Z = intersection1.Z; +// } +// +// } +// else +// { +// throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level."); +// } +// } +// } - private void AdaptPL1ForNonWaterRetainingObject(ref PLLine pl1Line) - { - // check if nwo points are available as CharacteristicPoints - var nwo1 = this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1); - var nwo2 = this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint2); - var nwo3 = this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint3); - var nwo4 = this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4); - if ((nwo1 != null) && (nwo2 != null) && (nwo3 != null) && (nwo4 != null)) - { +// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1And2(GeometryPoint nwo2, GeometryPoint nwo3, GeometryPoint nwo4, PLLine pl1Line, PLLinePoint nwo3Pl, PLLinePoint intersection1, PLLinePoint intersection2) +// { +// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z), EndPoint = new GeometryPoint(nwo4.X, 0, nwo4.Z) }; +// var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(intersection1.X, 0, intersection1.Z), EndPoint = new GeometryPoint(nwo4.X, 0, intersection1.Z) }; +// var isp = new GeometryPoint(); +// if (LineHelper.GetStrictIntersectionPoint(lineNWO, linePL, ref isp)) +// { +// var newP1 = pl1Line.EnsurePointAtX(intersection1.X, GeometryPoint.Precision); +// newP1.Z = intersection1.Z; +// var newP2 = pl1Line.EnsurePointAtX(isp.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP2.Z = intersection1.Z; +// var newP3 = pl1Line.EnsurePointAtX(intersection2.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP3.Z = intersection2.Z; +// } +// else +// { +// var lineNWOb = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z), EndPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z) }; +// if (LineHelper.GetStrictIntersectionPoint(lineNWOb, linePL, ref isp)) +// { +// var newP1 = pl1Line.EnsurePointAtX(intersection1.X, GeometryPoint.Precision); +// newP1.Z = intersection1.Z; +// var newP2 = pl1Line.EnsurePointAtX(isp.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP2.Z = intersection1.Z; +// var newP3 = pl1Line.EnsurePointAtX(nwo3Pl.X, GeometryPoint.Precision); +// newP3.Z = nwo3Pl.Z; +// if (nwo3Pl.X < intersection2.X) +// { +// var newP4 = pl1Line.EnsurePointAtX(intersection2.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP4.Z = intersection2.Z; +// } +// } +// else +// { +// throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level."); +// } +// } +// } - // Find all points in the Pl line that (might) coincide with the NWO - IEnumerable plPointsToBeMoved = FindAllPlLinePointsAtNWOLocation(pl1Line); +// private void RemoveAllWaterFromNonWaterRetainingObject(GeometryPoint nwo1, PLLine pl1Line, PLLinePoint nwo1Pl, PLLinePoint nwo2Pl, PLLinePoint nwo3Pl, PLLinePoint nwo4Pl, PLLinePoint intersection1, PLLinePoint intersection2, IEnumerable plPointsToBeMoved) +// { +// if ((nwo1.X >= this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X) || +// ((intersection1 != null) && (intersection2 != null))) +// { +// // Move all the points in the pl line itself that need to be moved to below the surfaceline. +// MoveSelectedPLLinePointsBelowSurfaceLine(plPointsToBeMoved); +// +// // now add all extra points to the pl line +// if (nwo1Pl != null) +// { +// var newP = pl1Line.EnsurePointAtX(nwo1Pl.X, GeometryPoint.Precision); +// newP.Z = nwo1Pl.Z; +// } +// if (nwo2Pl != null) +// { +// var newP = pl1Line.EnsurePointAtX(nwo2Pl.X, GeometryPoint.Precision); +// newP.Z = nwo2Pl.Z; +// } +// if (nwo3Pl != null) +// { +// var newP = pl1Line.EnsurePointAtX(nwo3Pl.X, GeometryPoint.Precision); +// newP.Z = nwo3Pl.Z; +// } +// if (nwo4Pl != null) +// { +// var newP = pl1Line.EnsurePointAtX(nwo4Pl.X, GeometryPoint.Precision); +// newP.Z = nwo4Pl.Z; +// } +// // Note: for intersection points, apply offset in X direction not in Z. +// if (intersection1 != null) +// { +// var newP = pl1Line.EnsurePointAtX(intersection1.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP.Z = intersection1.Z; +// } +// if (intersection2 != null) +// { +// var newP = pl1Line.EnsurePointAtX(intersection2.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP.Z = intersection2.Z; +// } +// pl1Line.DeleteCoinsidingPoints(GeometryPoint.Precision); +// } +// } - PLLinePoint nwo1Pl = null; - PLLinePoint nwo2Pl = null; - PLLinePoint nwo3Pl = null; - PLLinePoint nwo4Pl = null; +// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2(GeometryPoint nwo1, GeometryPoint nwo2, GeometryPoint nwo3, PLLine pl1Line, PLLinePoint nwo1Pl, PLLinePoint nwo2Pl, PLLinePoint nwo3Pl, PLLinePoint intersection2) +// { +// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, nwo1.Z), EndPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z) }; +// var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, intersection2.Z), EndPoint = new GeometryPoint(intersection2.X, 0, intersection2.Z) }; +// var isp = new GeometryPoint(); +// if (LineHelper.GetStrictIntersectionPoint(lineNWO, linePL, ref isp)) +// { +// var newP1 = pl1Line.EnsurePointAtX(intersection2.X, GeometryPoint.Precision); +// newP1.Z = intersection2.Z; +// var newP2 = pl1Line.EnsurePointAtX(isp.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP2.Z = intersection2.Z; +// if (nwo1Pl != null) +// { +// var newP3 = pl1Line.EnsurePointAtX(nwo1Pl.X, GeometryPoint.Precision); +// newP3.Z = nwo1Pl.Z; +// } +// } +// else +// { +// var lineNWOb = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z), EndPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z) }; +// if (LineHelper.GetStrictIntersectionPoint(lineNWOb, linePL, ref isp)) +// { +// var newP1 = pl1Line.EnsurePointAtX(intersection2.X, GeometryPoint.Precision); +// newP1.Z = intersection2.Z; +// var newP2 = pl1Line.EnsurePointAtX(isp.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP2.Z = intersection2.Z; +// if (nwo2Pl != null) +// { +// var newP3 = pl1Line.EnsurePointAtX(nwo2Pl.X, GeometryPoint.Precision); +// newP3.Z = nwo2Pl.Z; +// if ((nwo1Pl != null) && (nwo2Pl.X > nwo1Pl.X)) +// { +// var newP4 = pl1Line.EnsurePointAtX(nwo1Pl.X, GeometryPoint.Precision); +// newP4.Z = nwo1Pl.Z; +// } +// } +// } +// else +// { +// throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level."); +// } +// } +// } - // For NWO point, determine whether a pl point has to be added - if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo1) != PLLinePointPositionXzType.AbovePLLine) - { - nwo1Pl = new PLLinePoint(nwo1.X, nwo1.Z - cOffsetPhreaticLineBelowSurface); - } - if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo2) != PLLinePointPositionXzType.AbovePLLine) - { - nwo2Pl = new PLLinePoint(nwo2.X, nwo2.Z - cOffsetPhreaticLineBelowSurface); - } - if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo3) != PLLinePointPositionXzType.AbovePLLine) - { - nwo3Pl = new PLLinePoint(nwo3.X, nwo3.Z - cOffsetPhreaticLineBelowSurface); - } - if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo4) != PLLinePointPositionXzType.AbovePLLine) - { - nwo4Pl = new PLLinePoint(nwo4.X, nwo4.Z - cOffsetPhreaticLineBelowSurface); - } +// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1(GeometryPoint nwo2, GeometryPoint nwo3, GeometryPoint nwo4, PLLine pl1Line, PLLinePoint nwo3Pl, PLLinePoint nwo4Pl, PLLinePoint intersection1) +// { +// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z), EndPoint = new GeometryPoint(nwo4.X, 0, nwo4.Z) }; +// var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(intersection1.X, 0, intersection1.Z), EndPoint = new GeometryPoint(nwo4.X, 0, intersection1.Z) }; +// var isp = new GeometryPoint(); +// if (LineHelper.GetStrictIntersectionPoint(lineNWO, linePL, ref isp)) +// { +// var newP1 = pl1Line.EnsurePointAtX(intersection1.X, GeometryPoint.Precision); +// newP1.Z = intersection1.Z; +// var newP2 = pl1Line.EnsurePointAtX(isp.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP2.Z = intersection1.Z; +// if (nwo4Pl != null) +// { +// var newP3 = pl1Line.EnsurePointAtX(nwo4Pl.X, GeometryPoint.Precision); +// newP3.Z = nwo4Pl.Z; +// } +// } +// else +// { +// var lineNWOb = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z), EndPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z) }; +// if (LineHelper.GetStrictIntersectionPoint(lineNWOb, linePL, ref isp)) +// { +// var newP1 = pl1Line.EnsurePointAtX(intersection1.X, GeometryPoint.Precision); +// newP1.Z = intersection1.Z; +// var newP2 = pl1Line.EnsurePointAtX(isp.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); +// newP2.Z = intersection1.Z; +// if (nwo3Pl != null) +// { +// var newP3 = pl1Line.EnsurePointAtX(nwo3Pl.X, GeometryPoint.Precision); +// newP3.Z = nwo3Pl.Z; +// if ((nwo4Pl != null) && (nwo4Pl.X > nwo3Pl.X)) +// { +// var newP4 = pl1Line.EnsurePointAtX(nwo4Pl.X, GeometryPoint.Precision); +// newP4.Z = nwo4Pl.Z; +// } +// } +// } +// else +// { +// throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level."); +// } +// } +// } - // Find the intersections of pl line and NWO and handle these - // Intersection between nwo point1 and nwo point2 only when nwo point1 is above pl line and nwo point2 is below plLine - PLLinePoint intersection1 = null; - if ((nwo1Pl == null) && (nwo2Pl != null)) - { - var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, nwo1.Z), EndPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z) }; - var ips = pl1Line.IntersectionPointsXzWithLineXz(lineNWO); - if (ips.Count > 0) - { - intersection1 = new PLLinePoint(ips.First().X, ips.First().Z); - } - } - // Intersection between nwo point3 and nwo point4 only when nwo point3 is below pl line and nwo point4 is above plLine - PLLinePoint intersection2 = null; - if ((nwo3Pl != null) && (nwo4Pl == null)) - { - var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z), EndPoint = new GeometryPoint(nwo4.X, 0, nwo4.Z) }; - var ips = pl1Line.IntersectionPointsXzWithLineXz(lineNWO); - if (ips.Count > 0) - { - intersection2 = new PLLinePoint(ips.Last().X, ips.Last().Z); - } - } +// private void MoveSelectedPLLinePointsBelowSurfaceLine(IEnumerable plPointsToBeMoved) +// { +// foreach (var plLinePoint in plPointsToBeMoved) +// { +// // Determine which of these points must be moved and move them +// if (this.surfaceLine.Geometry.PositionXzOfPointRelatedToExtrapolatedLine(plLinePoint) != +// RelativeXzPosition.BelowGeometricLine) +// { +// plLinePoint.Z = this.surfaceLine.Geometry.GetZatX(plLinePoint.X) - cOffsetPhreaticLineBelowSurface; +// } +// } +// } - // Handle making the NWO empty - if ((NWOPhreaticAdaption != null) && (NWOPhreaticAdaption == PhreaticAdaptionType.MakeEmpty)) - { - // for the polderside, the pl line is always allowed to be adapted. For the riverside, the pl line may only be adapted when the original waterlevel is runs through the nwo. - RemoveAllWaterFromNonWaterRetainingObject(nwo1, pl1Line, nwo1Pl, nwo2Pl, nwo3Pl, nwo4Pl, intersection1, intersection2, plPointsToBeMoved); - } - // Handle making the waterlevel horizontal in the NWO at the Riverside when needed (Polderside is already done when needed, see CreatePhreaticLineSegmentsInShoulderAndPolder. - if ((NWOPhreaticAdaption != null) && (NWOPhreaticAdaption == PhreaticAdaptionType.None)) - { - // For the riverside, the pl line may only be adapted when the original waterlevel is runs through the nwo and is not already level. - if ((nwo1.X <= this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X) && ((intersection1 != null) || (intersection2 != null))) - { - double requiredWaterLevel; - // Check whether adaption of intersection points is needed - if (intersection2 == null) - { - // only intersection 1 avaialable so add intersection 2 - // first see if nwo3/4 intersects, if not try nwo2/3. If still no intersection found valid level not possible, raise error - MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1(nwo2, nwo3, nwo4, pl1Line, nwo3Pl, nwo4Pl, intersection1); - requiredWaterLevel = intersection1.Z; - } - else - { - if (intersection1 == null) - { - // only intersection 2 avaialable so add intersection 1 - // first see if nwo1/2 intersects, if not try nwo2/3. If still no intersection found valid level not possible, raise error - MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2(nwo1, nwo2, nwo3, pl1Line, nwo1Pl, nwo2Pl, nwo3Pl, intersection2); - requiredWaterLevel = intersection2.Z; - } - else - { - // intersection 1 and intersection 2 available. Only act when levels were different. - requiredWaterLevel = Math.Min(intersection1.Z, intersection2.Z); - if ((Math.Abs(intersection1.Z - intersection2.Z) > GeometryPoint.Precision)) - { - if (intersection1.Z < intersection2.Z) - { - // make level in NWO intersection1.Z - MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1And2(nwo2, nwo3, nwo4, pl1Line, nwo3Pl, intersection1, intersection2); - } - else - { - // make level in NWO intersection2.Z - MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2And1(nwo1, nwo2, nwo3, pl1Line, nwo2Pl, intersection1, intersection2); - } - - } - } - } - - // Move all the points in the pl line itself that need to be moved to the horizontal proper level. - foreach (var plLinePoint in plPointsToBeMoved) - { - plLinePoint.Z = requiredWaterLevel; - } - pl1Line.DeleteCoinsidingPoints(GeometryPoint.Precision); - } - } - } - } - - private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2And1(GeometryPoint nwo1, GeometryPoint nwo2, GeometryPoint nwo3, PLLine pl1Line, PLLinePoint nwo2Pl, PLLinePoint intersection1, PLLinePoint intersection2) - { - var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, nwo1.Z), EndPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z) }; - var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, intersection2.Z), EndPoint = new GeometryPoint(intersection2.X, 0, intersection2.Z) }; - var isp = new GeometryPoint(); - if (LineHelper.GetStrictIntersectionPoint(lineNWO, linePL, ref isp)) - { - var newP1 = pl1Line.EnsurePointAtX(intersection2.X, GeometryPoint.Precision); - newP1.Z = intersection2.Z; - var newP2 = pl1Line.EnsurePointAtX(isp.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP2.Z = intersection2.Z; - var newP3 = pl1Line.EnsurePointAtX(intersection1.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP3.Z = intersection1.Z; - } - else - { - var lineNWOb = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z), EndPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z) }; - if (LineHelper.GetStrictIntersectionPoint(lineNWOb, linePL, ref isp)) - { - var newP1 = pl1Line.EnsurePointAtX(intersection2.X, GeometryPoint.Precision); - newP1.Z = intersection2.Z; - var newP2 = pl1Line.EnsurePointAtX(isp.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP2.Z = intersection2.Z; - var newP3 = pl1Line.EnsurePointAtX(nwo2Pl.X, GeometryPoint.Precision); - newP3.Z = nwo2Pl.Z; - if (nwo2Pl.X > intersection1.X) - { - var newP4 = pl1Line.EnsurePointAtX(intersection1.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP4.Z = intersection1.Z; - } - - } - else - { - throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level."); - } - } - } - - private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1And2(GeometryPoint nwo2, GeometryPoint nwo3, GeometryPoint nwo4, PLLine pl1Line, PLLinePoint nwo3Pl, PLLinePoint intersection1, PLLinePoint intersection2) - { - var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z), EndPoint = new GeometryPoint(nwo4.X, 0, nwo4.Z) }; - var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(intersection1.X, 0, intersection1.Z), EndPoint = new GeometryPoint(nwo4.X, 0, intersection1.Z) }; - var isp = new GeometryPoint(); - if (LineHelper.GetStrictIntersectionPoint(lineNWO, linePL, ref isp)) - { - var newP1 = pl1Line.EnsurePointAtX(intersection1.X, GeometryPoint.Precision); - newP1.Z = intersection1.Z; - var newP2 = pl1Line.EnsurePointAtX(isp.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP2.Z = intersection1.Z; - var newP3 = pl1Line.EnsurePointAtX(intersection2.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP3.Z = intersection2.Z; - } - else - { - var lineNWOb = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z), EndPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z) }; - if (LineHelper.GetStrictIntersectionPoint(lineNWOb, linePL, ref isp)) - { - var newP1 = pl1Line.EnsurePointAtX(intersection1.X, GeometryPoint.Precision); - newP1.Z = intersection1.Z; - var newP2 = pl1Line.EnsurePointAtX(isp.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP2.Z = intersection1.Z; - var newP3 = pl1Line.EnsurePointAtX(nwo3Pl.X, GeometryPoint.Precision); - newP3.Z = nwo3Pl.Z; - if (nwo3Pl.X < intersection2.X) - { - var newP4 = pl1Line.EnsurePointAtX(intersection2.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP4.Z = intersection2.Z; - } - } - else - { - throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level."); - } - } - } - - private void RemoveAllWaterFromNonWaterRetainingObject(GeometryPoint nwo1, PLLine pl1Line, PLLinePoint nwo1Pl, PLLinePoint nwo2Pl, PLLinePoint nwo3Pl, PLLinePoint nwo4Pl, PLLinePoint intersection1, PLLinePoint intersection2, IEnumerable plPointsToBeMoved) - { - if ((nwo1.X >= this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X) || - ((intersection1 != null) && (intersection2 != null))) - { - // Move all the points in the pl line itself that need to be moved to below the surfaceline. - MoveSelectedPLLinePointsBelowSurfaceLine(plPointsToBeMoved); - - // now add all extra points to the pl line - if (nwo1Pl != null) - { - var newP = pl1Line.EnsurePointAtX(nwo1Pl.X, GeometryPoint.Precision); - newP.Z = nwo1Pl.Z; - } - if (nwo2Pl != null) - { - var newP = pl1Line.EnsurePointAtX(nwo2Pl.X, GeometryPoint.Precision); - newP.Z = nwo2Pl.Z; - } - if (nwo3Pl != null) - { - var newP = pl1Line.EnsurePointAtX(nwo3Pl.X, GeometryPoint.Precision); - newP.Z = nwo3Pl.Z; - } - if (nwo4Pl != null) - { - var newP = pl1Line.EnsurePointAtX(nwo4Pl.X, GeometryPoint.Precision); - newP.Z = nwo4Pl.Z; - } - // Note: for intersection points, apply offset in X direction not in Z. - if (intersection1 != null) - { - var newP = pl1Line.EnsurePointAtX(intersection1.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP.Z = intersection1.Z; - } - if (intersection2 != null) - { - var newP = pl1Line.EnsurePointAtX(intersection2.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP.Z = intersection2.Z; - } - pl1Line.DeleteCoinsidingPoints(GeometryPoint.Precision); - } - } - - private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2(GeometryPoint nwo1, GeometryPoint nwo2, GeometryPoint nwo3, PLLine pl1Line, PLLinePoint nwo1Pl, PLLinePoint nwo2Pl, PLLinePoint nwo3Pl, PLLinePoint intersection2) - { - var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, nwo1.Z), EndPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z) }; - var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, intersection2.Z), EndPoint = new GeometryPoint(intersection2.X, 0, intersection2.Z) }; - var isp = new GeometryPoint(); - if (LineHelper.GetStrictIntersectionPoint(lineNWO, linePL, ref isp)) - { - var newP1 = pl1Line.EnsurePointAtX(intersection2.X, GeometryPoint.Precision); - newP1.Z = intersection2.Z; - var newP2 = pl1Line.EnsurePointAtX(isp.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP2.Z = intersection2.Z; - if (nwo1Pl != null) - { - var newP3 = pl1Line.EnsurePointAtX(nwo1Pl.X, GeometryPoint.Precision); - newP3.Z = nwo1Pl.Z; - } - } - else - { - var lineNWOb = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z), EndPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z) }; - if (LineHelper.GetStrictIntersectionPoint(lineNWOb, linePL, ref isp)) - { - var newP1 = pl1Line.EnsurePointAtX(intersection2.X, GeometryPoint.Precision); - newP1.Z = intersection2.Z; - var newP2 = pl1Line.EnsurePointAtX(isp.X - cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP2.Z = intersection2.Z; - if (nwo2Pl != null) - { - var newP3 = pl1Line.EnsurePointAtX(nwo2Pl.X, GeometryPoint.Precision); - newP3.Z = nwo2Pl.Z; - if ((nwo1Pl != null) && (nwo2Pl.X > nwo1Pl.X)) - { - var newP4 = pl1Line.EnsurePointAtX(nwo1Pl.X, GeometryPoint.Precision); - newP4.Z = nwo1Pl.Z; - } - } - } - else - { - throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level."); - } - } - } - - private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1(GeometryPoint nwo2, GeometryPoint nwo3, GeometryPoint nwo4, PLLine pl1Line, PLLinePoint nwo3Pl, PLLinePoint nwo4Pl, PLLinePoint intersection1) - { - var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z), EndPoint = new GeometryPoint(nwo4.X, 0, nwo4.Z) }; - var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(intersection1.X, 0, intersection1.Z), EndPoint = new GeometryPoint(nwo4.X, 0, intersection1.Z) }; - var isp = new GeometryPoint(); - if (LineHelper.GetStrictIntersectionPoint(lineNWO, linePL, ref isp)) - { - var newP1 = pl1Line.EnsurePointAtX(intersection1.X, GeometryPoint.Precision); - newP1.Z = intersection1.Z; - var newP2 = pl1Line.EnsurePointAtX(isp.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP2.Z = intersection1.Z; - if (nwo4Pl != null) - { - var newP3 = pl1Line.EnsurePointAtX(nwo4Pl.X, GeometryPoint.Precision); - newP3.Z = nwo4Pl.Z; - } - } - else - { - var lineNWOb = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z), EndPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z) }; - if (LineHelper.GetStrictIntersectionPoint(lineNWOb, linePL, ref isp)) - { - var newP1 = pl1Line.EnsurePointAtX(intersection1.X, GeometryPoint.Precision); - newP1.Z = intersection1.Z; - var newP2 = pl1Line.EnsurePointAtX(isp.X + cOffsetPhreaticLineBelowSurface, GeometryPoint.Precision); - newP2.Z = intersection1.Z; - if (nwo3Pl != null) - { - var newP3 = pl1Line.EnsurePointAtX(nwo3Pl.X, GeometryPoint.Precision); - newP3.Z = nwo3Pl.Z; - if ((nwo4Pl != null) && (nwo4Pl.X > nwo3Pl.X)) - { - var newP4 = pl1Line.EnsurePointAtX(nwo4Pl.X, GeometryPoint.Precision); - newP4.Z = nwo4Pl.Z; - } - } - } - else - { - throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level."); - } - } - } - - private void MoveSelectedPLLinePointsBelowSurfaceLine(IEnumerable plPointsToBeMoved) - { - foreach (var plLinePoint in plPointsToBeMoved) - { - // Determine which of these points must be moved and move them - if (this.surfaceLine.Geometry.PositionXzOfPointRelatedToExtrapolatedLine(plLinePoint) != - RelativeXzPosition.BelowGeometricLine) - { - plLinePoint.Z = this.surfaceLine.Geometry.GetZAtX(plLinePoint.X) - cOffsetPhreaticLineBelowSurface; - } - } - } - /// /// /// /// /// - private PLLines CreateAllPLLinesWithGaugesWithFallbackToExpertKnowledgeRRD(Location location) - { - var plLines = new PLLines(); +// private PLLines CreateAllPLLinesWithGaugesWithFallbackToExpertKnowledgeRRD(Location location) +// { +// var plLines = new PLLines(); +// +// foreach (PLLineType plLineType in Enum.GetValues(typeof(PLLineType))) +// { +// GaugePLLine gaugePLLine = (this.GaugePLLines != null) ? (this.GaugePLLines.FirstOrDefault(x => x.PLLineType == plLineType)) : null; +// if (gaugePLLine != null && location != null) +// { +// Boolean isUseWaterLevel = ((plLineType == PLLineType.PL1) || (plLineType == PLLineType.PL2)); +// plLines.Lines[plLineType] = CreatePLLineFromGauges(gaugePLLine, this.Gauges, location, isUseWaterLevel); +// } +// else +// plLines.Lines[plLineType] = CreatePLLineByExpertKnowledge(plLineType, location.DamType, location.SlopeDampingPiezometricHeightPolderSide); +// +// // currentPL1Line is needed when calculating uplift reduction for PL3 and Pl4 +// if (plLineType == PLLineType.PL1) +// { +// currentPL1Line = plLines.Lines[plLineType]; +// } +// } +// return plLines; +// } - foreach (PLLineType plLineType in Enum.GetValues(typeof(PLLineType))) - { - GaugePLLine gaugePLLine = (this.GaugePLLines != null) ? (this.GaugePLLines.FirstOrDefault(x => x.PLLineType == plLineType)) : null; - if (gaugePLLine != null && location != null) - { - Boolean isUseWaterLevel = ((plLineType == PLLineType.PL1) || (plLineType == PLLineType.PL2)); - plLines.Lines[plLineType] = CreatePLLineFromGauges(gaugePLLine, this.Gauges, location, isUseWaterLevel); - } - else - plLines.Lines[plLineType] = CreatePLLineByExpertKnowledge(plLineType, location.DamType, location.SlopeDampingPiezometricHeightPolderSide); - - // currentPL1Line is needed when calculating uplift reduction for PL3 and Pl4 - if (plLineType == PLLineType.PL1) - { - currentPL1Line = plLines.Lines[plLineType]; - } - } - return plLines; - } - /// /// Create all PLLines /// /// - public PLLines CreateAllPLLines(Location location) - { +// public PLLines CreateAllPLLines(Location location) +// { +// +// PLLines plLines = new PLLines(); +// switch (modelParametersForPLLines.PLLineCreationMethod) +// { +// case PLLineCreationMethod.ExpertKnowledgeLinearInDike: +// case PLLineCreationMethod.ExpertKnowledgeRRD: plLines = CreateAllPLLinesWithExpertKnowledge(location); +// break; +// case PLLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD: plLines = CreateAllPLLinesWithGaugesWithFallbackToExpertKnowledgeRRD(location); +// break; +// } +// +// +// // If PL Line2 does not exists, make it equal to PL line 4 +// if (!plLines.Lines[PLLineType.PL2].Exists()) +// { +// plLines.Lines[PLLineType.PL2] = plLines.Lines[PLLineType.PL4].Clone(); +// } +// +// if (!plLines.Lines[PLLineType.PL1].IsXAscending()) +// { +// throw new PLLinesCreatorException("PLLine 1 not an X-ascending polyline"); +// } +// +// return plLines; +// } - PLLines plLines = new PLLines(); - switch (modelParametersForPLLines.PLLineCreationMethod) - { - case PLLineCreationMethod.ExpertKnowledgeLinearInDike: - case PLLineCreationMethod.ExpertKnowledgeRRD: plLines = CreateAllPLLinesWithExpertKnowledge(location); - break; - case PLLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD: plLines = CreateAllPLLinesWithGaugesWithFallbackToExpertKnowledgeRRD(location); - break; - } - - - // If PL Line2 does not exists, make it equal to PL line 4 - if (!plLines.Lines[PLLineType.PL2].Exists()) - { - plLines.Lines[PLLineType.PL2] = plLines.Lines[PLLineType.PL4].Clone(); - } - - if (!plLines.Lines[PLLineType.PL1].IsXAscending()) - { - throw new PLLinesCreatorException("PLLine 1 not an X-ascending polyline"); - } - - return plLines; - } - /// /// /// @@ -1429,102 +1430,102 @@ /// /// /// - private PLLine CreatePLLineFromGauges(GaugePLLine gaugePLLine, IEnumerable gauges, Location location, Boolean useWaterLevel) - { - PLLine plLine = new PLLine(); +// private PLLine CreatePLLineFromGauges(GaugePLLine gaugePLLine, IEnumerable gauges, Location location, Boolean useWaterLevel) +// { +// PLLine plLine = new PLLine(); +// +// double? gaugeWaterLevelRiver = null; +// double? leftMostXAtRiverLevel = null; +// +// int pointIndex = 0; +// foreach (GaugePLLinePoint gaugePLLinePoint in gaugePLLine.Points) +// { +// +// double? localX = gaugePLLinePoint.X; +// double? localZ = gaugePLLinePoint.Z; +// +// if (gauges != null) +// { +// if (gaugePLLinePoint.GaugeIDX != null && gaugePLLinePoint.GaugeIDX != "") +// { +// Gauge gauge = (gauges.Where(x => x.Name == gaugePLLinePoint.GaugeIDX && x.Location == location)).FirstOrDefault(); +// if (gauge != null) +// localX = gauge.LocalX; +// else +// { +// throw new PLLinesCreatorException(String.Format("Gauge PL line {0} refers to an unknown gauge named '{1}' at X coordinate #{2}.", +// gaugePLLine.PLLineType.ToString(), gaugePLLinePoint.GaugeIDX, pointIndex)); +// } +// } +// if (gaugePLLinePoint.GaugeIDZ != null && gaugePLLinePoint.GaugeIDZ != "") +// { +// Gauge gauge = (gauges.Where(x => x.Name == gaugePLLinePoint.GaugeIDZ && x.Location == location)).FirstOrDefault(); +// if (gauge != null) +// { +// if ((!gauge.Value.HasValue) || (gauge.Value == GaugeMissVal)) +// throw new PLLinesCreatorException(String.Format("Value of gauge {0} at location {1} in gauge PL line of type {2} is undefined.", +// gauge.Name, location.Name, gaugePLLine.PLLineType.ToString())); +// localZ = gauge.Value; +// } +// else +// { +// throw new PLLinesCreatorException(String.Format("Gauge PL line {0} refers to an unknown gauge named '{1}' at Z coordinate #{2}.", +// gaugePLLine.PLLineType.ToString(), gaugePLLinePoint.GaugeIDZ, pointIndex)); +// } +// } +// } +// +// if (!localX.HasValue) +// throw new PLLinesCreatorException(String.Format("Gauge PL line {0}'s X coordinate #{1} is undefined.", gaugePLLine.PLLineType.ToString(), pointIndex)); +// else if (!localZ.HasValue) +// throw new PLLinesCreatorException(String.Format("Gauge PL line {0}'s value #{1} is undefined.", gaugePLLine.PLLineType.ToString(), pointIndex)); +// else +// { +// if (!leftMostXAtRiverLevel.HasValue || localX > leftMostXAtRiverLevel) +// { +// plLine.Points.Add(new PLLinePoint(localX.Value, localZ.Value)); +// if (useWaterLevel) +// { +// // Have to account for waterlevel +// if (!gaugeWaterLevelRiver.HasValue) +// { +// // Use first gauge as waterlevel +// gaugeWaterLevelRiver = localZ.Value; +// IList intersectionsAtX = this.surfaceLine.Geometry.IntersectionsXAtZ(gaugeWaterLevelRiver.Value); +// if (intersectionsAtX.Count() > 0) +// { +// // this is where the waterlevel intersects with the dike +// leftMostXAtRiverLevel = intersectionsAtX.First(); +// plLine.Points.Add(new PLLinePoint(leftMostXAtRiverLevel.Value, gaugeWaterLevelRiver.Value)); +// } +// else +// { +// // No intersection with dike; polder is flooded +// leftMostXAtRiverLevel = this.surfaceLine.Geometry.Points.Last().X; +// plLine.Points.Add(new PLLinePoint(this.surfaceLine.Geometry.Points.Last().X, gaugeWaterLevelRiver.Value)); +// } +// } +// } +// else +// { +// // In this case no intersection for this Plline with the dike will be considered +// leftMostXAtRiverLevel = this.surfaceLine.Geometry.Points.First().X; +// } +// } +// } +// +// pointIndex++; +// } +// +// if (plLine.Points.Count() > 0) +// { +// plLine.Points.First().X = this.surfaceLine.Geometry.Points.First().X; +// plLine.Points.Last().X = this.surfaceLine.Geometry.Points.Last().X; +// } +// +// return plLine; +// } - double? gaugeWaterLevelRiver = null; - double? leftMostXAtRiverLevel = null; - - int pointIndex = 0; - foreach (GaugePLLinePoint gaugePLLinePoint in gaugePLLine.Points) - { - - double? localX = gaugePLLinePoint.X; - double? localZ = gaugePLLinePoint.Z; - - if (gauges != null) - { - if (gaugePLLinePoint.GaugeIDX != null && gaugePLLinePoint.GaugeIDX != "") - { - Gauge gauge = (gauges.Where(x => x.Name == gaugePLLinePoint.GaugeIDX && x.Location == location)).FirstOrDefault(); - if (gauge != null) - localX = gauge.LocalX; - else - { - throw new PLLinesCreatorException(String.Format("Gauge PL line {0} refers to an unknown gauge named '{1}' at X coordinate #{2}.", - gaugePLLine.PLLineType.ToString(), gaugePLLinePoint.GaugeIDX, pointIndex)); - } - } - if (gaugePLLinePoint.GaugeIDZ != null && gaugePLLinePoint.GaugeIDZ != "") - { - Gauge gauge = (gauges.Where(x => x.Name == gaugePLLinePoint.GaugeIDZ && x.Location == location)).FirstOrDefault(); - if (gauge != null) - { - if ((!gauge.Value.HasValue) || (gauge.Value == GaugeMissVal)) - throw new PLLinesCreatorException(String.Format("Value of gauge {0} at location {1} in gauge PL line of type {2} is undefined.", - gauge.Name, location.Name, gaugePLLine.PLLineType.ToString())); - localZ = gauge.Value; - } - else - { - throw new PLLinesCreatorException(String.Format("Gauge PL line {0} refers to an unknown gauge named '{1}' at Z coordinate #{2}.", - gaugePLLine.PLLineType.ToString(), gaugePLLinePoint.GaugeIDZ, pointIndex)); - } - } - } - - if (!localX.HasValue) - throw new PLLinesCreatorException(String.Format("Gauge PL line {0}'s X coordinate #{1} is undefined.", gaugePLLine.PLLineType.ToString(), pointIndex)); - else if (!localZ.HasValue) - throw new PLLinesCreatorException(String.Format("Gauge PL line {0}'s value #{1} is undefined.", gaugePLLine.PLLineType.ToString(), pointIndex)); - else - { - if (!leftMostXAtRiverLevel.HasValue || localX > leftMostXAtRiverLevel) - { - plLine.Points.Add(new PLLinePoint(localX.Value, localZ.Value)); - if (useWaterLevel) - { - // Have to account for waterlevel - if (!gaugeWaterLevelRiver.HasValue) - { - // Use first gauge as waterlevel - gaugeWaterLevelRiver = localZ.Value; - IList intersectionsAtX = this.surfaceLine.Geometry.IntersectionsXAtZ(gaugeWaterLevelRiver.Value); - if (intersectionsAtX.Count() > 0) - { - // this is where the waterlevel intersects with the dike - leftMostXAtRiverLevel = intersectionsAtX.First(); - plLine.Points.Add(new PLLinePoint(leftMostXAtRiverLevel.Value, gaugeWaterLevelRiver.Value)); - } - else - { - // No intersection with dike; polder is flooded - leftMostXAtRiverLevel = this.surfaceLine.Geometry.Points.Last().X; - plLine.Points.Add(new PLLinePoint(this.surfaceLine.Geometry.Points.Last().X, gaugeWaterLevelRiver.Value)); - } - } - } - else - { - // In this case no intersection for this Plline with the dike will be considered - leftMostXAtRiverLevel = this.surfaceLine.Geometry.Points.First().X; - } - } - } - - pointIndex++; - } - - if (plLine.Points.Count() > 0) - { - plLine.Points.First().X = this.surfaceLine.Geometry.Points.First().X; - plLine.Points.Last().X = this.surfaceLine.Geometry.Points.Last().X; - } - - return plLine; - } - /// /// Validate of all required characteristic points exists /// @@ -1583,34 +1584,34 @@ phreaticLine.Points.Add(pointBelowHighLevel); break; - case PLLineCreationMethod.ExpertKnowledgeRRD: - //Add points below surface of dike talud riverside until toe of dike riverside - foreach (GeometryPoint point in SurfaceLine.Geometry.Points.Where( - point => point.X > intersectionLowWaterLevelWithDike.X && - point.X <= pointDikeToeAtRiver.X)) - { - if (!surfaceLine.IsNonWaterRetainingObjectPoint(point)) - { - phreaticLine.Points.Add(new PLLinePoint(point.X, point.Z - cPLLineOffsetBelowSurface)); - } - } - - // Add points below crest of dike - double offsetDikeTopAtRiver = this.waterLevelRiverHigh - PlLineOffsetBelowDikeTopAtRiver; - double offsetDikeTopAtPolder = this.waterLevelRiverHigh - PlLineOffsetBelowDikeTopAtPolder; - GeometryPoint pointDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver); - GeometryPoint pointDikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); - if (pointDikeTopAtRiver != null) - phreaticLine.Points.Add(new PLLinePoint(pointDikeTopAtRiver.X, offsetDikeTopAtRiver)); - - if (pointDikeTopAtRiver != null && pointDikeTopAtPolder != null) - { - CreateOptionalPointAtDikeCrestMiddle(phreaticLine, pointDikeTopAtRiver, pointDikeTopAtPolder); - } - - if (pointDikeTopAtPolder != null) - phreaticLine.Points.Add(new PLLinePoint(pointDikeTopAtPolder.X, offsetDikeTopAtPolder)); - break; +// case PLLineCreationMethod.ExpertKnowledgeRRD: +// //Add points below surface of dike talud riverside until toe of dike riverside +// foreach (GeometryPoint point in SurfaceLine.Geometry.Points.Where( +// point => point.X > intersectionLowWaterLevelWithDike.X && +// point.X <= pointDikeToeAtRiver.X)) +// { +// if (!surfaceLine.IsNonWaterRetainingObjectPoint(point)) +// { +// phreaticLine.Points.Add(new PLLinePoint(point.X, point.Z - cPLLineOffsetBelowSurface)); +// } +// } +// +// // Add points below crest of dike +// double offsetDikeTopAtRiver = this.waterLevelRiverHigh - PlLineOffsetBelowDikeTopAtRiver; +// double offsetDikeTopAtPolder = this.waterLevelRiverHigh - PlLineOffsetBelowDikeTopAtPolder; +// GeometryPoint pointDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver); +// GeometryPoint pointDikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); +// if (pointDikeTopAtRiver != null) +// phreaticLine.Points.Add(new PLLinePoint(pointDikeTopAtRiver.X, offsetDikeTopAtRiver)); +// +// if (pointDikeTopAtRiver != null && pointDikeTopAtPolder != null) +// { +// CreateOptionalPointAtDikeCrestMiddle(phreaticLine, pointDikeTopAtRiver, pointDikeTopAtPolder); +// } +// +// if (pointDikeTopAtPolder != null) +// phreaticLine.Points.Add(new PLLinePoint(pointDikeTopAtPolder.X, offsetDikeTopAtPolder)); +// break; } } @@ -1676,183 +1677,183 @@ /// /// /// - private void CreatePhreaticLineSegmentsInShoulderAndPolder(PLLine phreaticLine) - { - PLLinePoint intersectionPolderLevelWithDike = DetermineIntersectionBetweenPolderLevelAndDike(this.WaterLevelPolder); - GeometryPoint dikeToeAtPolderPoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); +// private void CreatePhreaticLineSegmentsInShoulderAndPolder(PLLine phreaticLine) +// { +// PLLinePoint intersectionPolderLevelWithDike = DetermineIntersectionBetweenPolderLevelAndDike(this.WaterLevelPolder); +// GeometryPoint dikeToeAtPolderPoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); +// +// double maxXCoordinateSurface = surfaceLine.Geometry.Points.Max(x => x.X); +// if (modelParametersForPLLines.PLLineCreationMethod != PLLineCreationMethod.ExpertKnowledgeLinearInDike) +// { +// // Points created below are points starting at shoulder point to the right +// GeometryPoint shoulderBaseInsidePoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); +// if (shoulderBaseInsidePoint != null) +// { +// double zLevel = Math.Min(phreaticLine.Points.Last().Z, +// shoulderBaseInsidePoint.Z - +// Math.Max(cOffsetPhreaticLineBelowSurface, PlLineOffsetBelowShoulderBaseInside)); +// zLevel = Math.Max(zLevel, this.WaterLevelPolder); +// // Add point if it lies left of intersection of polderlevel with dike) +// if ((intersectionPolderLevelWithDike == null) || +// (intersectionPolderLevelWithDike.X > shoulderBaseInsidePoint.X)) +// { +// phreaticLine.Points.Add(new PLLinePoint(shoulderBaseInsidePoint.X, zLevel)); +// } +// +// if (UsePlLineOffsetFactorBelowShoulderCrest.HasValue && UsePlLineOffsetFactorBelowShoulderCrest.Value && +// PlLineOffsetFactorBelowShoulderCrest != null && dikeToeAtPolderPoint != null) +// { +// GeometryPoint shoulderTopInsidePoint = +// surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); +// if (shoulderTopInsidePoint != null) +// { +// zLevel = dikeToeAtPolderPoint.Z + (PlLineOffsetFactorBelowShoulderCrest.Value* +// (shoulderTopInsidePoint.Z - dikeToeAtPolderPoint.Z)); +// zLevel = Math.Min(zLevel, shoulderTopInsidePoint.Z - cOffsetPhreaticLineBelowSurface); +// zLevel = Math.Min(zLevel, phreaticLine.Points.Last().Z); +// zLevel = Math.Max(zLevel, this.WaterLevelPolder); +// phreaticLine.Points.Add(new PLLinePoint(shoulderTopInsidePoint.X, zLevel)); +// } +// } +// } +// } +// +// GeometryPoint ditchDikeSidePoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); +// if (dikeToeAtPolderPoint != null) +// { +// +// double zLevel = Math.Min(phreaticLine.Points.Last().Z, dikeToeAtPolderPoint.Z - Math.Max(cOffsetPhreaticLineBelowSurface, PlLineOffsetBelowDikeToeAtPolder)); +// if (ditchDikeSidePoint != null) +// { +// if (ditchDikeSidePoint.LocationEquals(dikeToeAtPolderPoint)) +// { +// // If DikeToeAtPolder is same as DitchDikeSide pl1 should always go to polderlevel at this point +// zLevel = this.WaterLevelPolder; +// } +// } +// zLevel = Math.Max(zLevel, this.WaterLevelPolder); +// // Add point if it lies left of intersection of polderlevel with dike +// if ((intersectionPolderLevelWithDike == null) || (intersectionPolderLevelWithDike.X > dikeToeAtPolderPoint.X)) +// { +// phreaticLine.Points.Add(new PLLinePoint(dikeToeAtPolderPoint.X, zLevel)); +// } +// } +// +// if (intersectionPolderLevelWithDike != null) +// { +// phreaticLine.Points.Add(intersectionPolderLevelWithDike); +// } +// +// var isDitchPresent = (ditchDikeSidePoint != null); +// var isNonWaterRetainingOjectPresent = ((NWOPhreaticAdaption != null) && surfaceLine.HasAnnotation(CharacteristicPointType.NonWaterRetainingObjectPoint1)); +// var adjustDitch = false; +// // Handle making the waterlevel horizontal in the NWO at the Polderside when needed (For Riverside see AdaptPL1ForNonWaterRetainingObject). +// var nonWaterRetainingGeometryPoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1); +// if (isNonWaterRetainingOjectPresent && (NWOPhreaticAdaption != PhreaticAdaptionType.Fill) && +// (nonWaterRetainingGeometryPoint.X >= surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X)) +// { +// // if there is a ditch and it is to the left of the NWO, then only the ditch needs to be adjusted and the NWO will be correct automatically. +// // if there is a ditch but it is to the right of the NWO, the NWO needs adjusting and the Ditch will be correct automatically. +// // if there is no ditch then the NWO needs adjusting. +// if (isDitchPresent) +// { +// adjustDitch = (nonWaterRetainingGeometryPoint.X >= surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X); +// } +// if (!adjustDitch) +// { +// GeometryPoint nw1 = nonWaterRetainingGeometryPoint; +// int surfacePointIndex = surfaceLine.Geometry.Points.IndexOf(nw1); +// AdjustForDitchAndOrNonWaterRetainingObjectatPolderSide(phreaticLine, surfacePointIndex); +// } +// } +// else +// { +// // No (relevant) NWO so enable handling of ditch. +// // If there is a ditch but there is also a NWO to the right of it at polder side, then do not adjust the ditch. Do in all other cases. +// // First see if there is a NWO. +// adjustDitch = !isNonWaterRetainingOjectPresent; +// if (!adjustDitch) +// { +// // there is a NWO, check the position +// adjustDitch = +// !((isDitchPresent) && +// (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).X >= +// surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X) && +// (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).X <= +// surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide).X)); +// } +// } +// // if the NWO is not there or irrelevant and there is a ditch, then adjust it. +// if ((adjustDitch) && (isDitchPresent)) +// { +// int surfacePointIndex = surfaceLine.Geometry.Points.IndexOf(ditchDikeSidePoint); +// AdjustForDitchAndOrNonWaterRetainingObjectatPolderSide(phreaticLine, surfacePointIndex); +// } +// else +// { +// // if no ditch then the PL1 will continue horizontally until the end of the profile +// // another choice could be to let the PL1 go to polderlevel at the end of the profile, but that could be too optimistic for uplift. +// // Discussion about this was done between Vastenburg, Knoeff and The. +// // After a renewed discussion with Vastenburg, Van der Zwan and Bka, it has been decided that the PL1 should follow the +// // surfaceline (with offset) until either end of surface line or polder level. Note: this is only needed when the phreatic level +// // at dike toe is above polder level. +// if ((!isNonWaterRetainingOjectPresent) && (!isDitchPresent)) +// { +// if (phreaticLine.Points[phreaticLine.Points.Count - 1].Z > WaterLevelPolder) +// { +// AddPhreaticLineAlongSurfaceLevel(phreaticLine); +// } +// } +// } +// +// //Validate if endpoint surface has reached +// if (phreaticLine.Points.Last().X != maxXCoordinateSurface) +// { +// PLLinePoint endPoint = new PLLinePoint(maxXCoordinateSurface, phreaticLine.Points.Last().Z); +// phreaticLine.Points.Add(endPoint); +// } +// } - double maxXCoordinateSurface = surfaceLine.Geometry.Points.Max(x => x.X); - if (modelParametersForPLLines.PLLineCreationMethod != PLLineCreationMethod.ExpertKnowledgeLinearInDike) - { - // Points created below are points starting at shoulder point to the right - GeometryPoint shoulderBaseInsidePoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); - if (shoulderBaseInsidePoint != null) - { - double zLevel = Math.Min(phreaticLine.Points.Last().Z, - shoulderBaseInsidePoint.Z - - Math.Max(cOffsetPhreaticLineBelowSurface, PlLineOffsetBelowShoulderBaseInside)); - zLevel = Math.Max(zLevel, this.WaterLevelPolder); - // Add point if it lies left of intersection of polderlevel with dike) - if ((intersectionPolderLevelWithDike == null) || - (intersectionPolderLevelWithDike.X > shoulderBaseInsidePoint.X)) - { - phreaticLine.Points.Add(new PLLinePoint(shoulderBaseInsidePoint.X, zLevel)); - } +// private void AddPhreaticLineAlongSurfaceLevel(PLLine phreaticLine) +// { +// // Add phreatic point at offset below every surface line point as long as depth > polder level. Else determine the +// // proper position of the point at polder level (intersection) and stop. +// var surfacePointIndex = surfaceLine.Geometry.Points.IndexOf(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder)) + 1; +// bool intersected = false; +// for (int i = surfacePointIndex; i < surfaceLine.Geometry.Points.Count; i++) +// { +// double z = Math.Max(waterLevelPolder, surfaceLine.Geometry.Points[i].Z - PlLineOffsetBelowDikeToeAtPolder); +// double x = surfaceLine.Geometry.Points[i].X; +// if (waterLevelPolder > surfaceLine.Geometry.Points[i].Z - PlLineOffsetBelowDikeToeAtPolder) +// { +// // Determine intersection between would be phreatic segment and polderlevel. Add that as next point. +// Line waterLevelPolderLine = new Line(new GeometryPoint(surfaceLine.Geometry.Points.First().X, WaterLevelPolder), +// new GeometryPoint(surfaceLine.Geometry.Points.Last().X, 0, WaterLevelPolder)); +// Line slopeLine = new Line(new GeometryPoint(phreaticLine.Points[phreaticLine.Points.Count - 1].X, phreaticLine.Points[phreaticLine.Points.Count - 1].Z), +// new GeometryPoint(surfaceLine.Geometry.Points[i].X, surfaceLine.Geometry.Points[i].Z - PlLineOffsetBelowDikeToeAtPolder)); +// GeometryPoint intersectionPoint = new GeometryPoint(); +// if (waterLevelPolderLine.IntersectsZ(slopeLine, out intersectionPoint)) +// { +// x = intersectionPoint.X; +// } +// intersected = true; +// } +// PLLinePoint point = new PLLinePoint(x, z); +// phreaticLine.Points.Add(point); +// if (intersected) +// { +// break; +// } +// } +// } - if (UsePlLineOffsetFactorBelowShoulderCrest.HasValue && UsePlLineOffsetFactorBelowShoulderCrest.Value && - PlLineOffsetFactorBelowShoulderCrest != null && dikeToeAtPolderPoint != null) - { - GeometryPoint shoulderTopInsidePoint = - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); - if (shoulderTopInsidePoint != null) - { - zLevel = dikeToeAtPolderPoint.Z + (PlLineOffsetFactorBelowShoulderCrest.Value* - (shoulderTopInsidePoint.Z - dikeToeAtPolderPoint.Z)); - zLevel = Math.Min(zLevel, shoulderTopInsidePoint.Z - cOffsetPhreaticLineBelowSurface); - zLevel = Math.Min(zLevel, phreaticLine.Points.Last().Z); - zLevel = Math.Max(zLevel, this.WaterLevelPolder); - phreaticLine.Points.Add(new PLLinePoint(shoulderTopInsidePoint.X, zLevel)); - } - } - } - } - - GeometryPoint ditchDikeSidePoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); - if (dikeToeAtPolderPoint != null) - { - - double zLevel = Math.Min(phreaticLine.Points.Last().Z, dikeToeAtPolderPoint.Z - Math.Max(cOffsetPhreaticLineBelowSurface, PlLineOffsetBelowDikeToeAtPolder)); - if (ditchDikeSidePoint != null) - { - if (ditchDikeSidePoint.LocationEquals(dikeToeAtPolderPoint)) - { - // If DikeToeAtPolder is same as DitchDikeSide pl1 should always go to polderlevel at this point - zLevel = this.WaterLevelPolder; - } - } - zLevel = Math.Max(zLevel, this.WaterLevelPolder); - // Add point if it lies left of intersection of polderlevel with dike - if ((intersectionPolderLevelWithDike == null) || (intersectionPolderLevelWithDike.X > dikeToeAtPolderPoint.X)) - { - phreaticLine.Points.Add(new PLLinePoint(dikeToeAtPolderPoint.X, zLevel)); - } - } - - if (intersectionPolderLevelWithDike != null) - { - phreaticLine.Points.Add(intersectionPolderLevelWithDike); - } - - var isDitchPresent = (ditchDikeSidePoint != null); - var isNonWaterRetainingOjectPresent = ((NWOPhreaticAdaption != null) && surfaceLine.HasAnnotation(CharacteristicPointType.NonWaterRetainingObjectPoint1)); - var adjustDitch = false; - // Handle making the waterlevel horizontal in the NWO at the Polderside when needed (For Riverside see AdaptPL1ForNonWaterRetainingObject). - var nonWaterRetainingGeometryPoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1); - if (isNonWaterRetainingOjectPresent && (NWOPhreaticAdaption != PhreaticAdaptionType.Fill) && - (nonWaterRetainingGeometryPoint.X >= surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X)) - { - // if there is a ditch and it is to the left of the NWO, then only the ditch needs to be adjusted and the NWO will be correct automatically. - // if there is a ditch but it is to the right of the NWO, the NWO needs adjusting and the Ditch will be correct automatically. - // if there is no ditch then the NWO needs adjusting. - if (isDitchPresent) - { - adjustDitch = (nonWaterRetainingGeometryPoint.X >= surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X); - } - if (!adjustDitch) - { - GeometryPoint nw1 = nonWaterRetainingGeometryPoint; - int surfacePointIndex = surfaceLine.Geometry.Points.IndexOf(nw1); - AdjustForDitchAndOrNonWaterRetainingObjectatPolderSide(phreaticLine, surfacePointIndex); - } - } - else - { - // No (relevant) NWO so enable handling of ditch. - // If there is a ditch but there is also a NWO to the right of it at polder side, then do not adjust the ditch. Do in all other cases. - // First see if there is a NWO. - adjustDitch = !isNonWaterRetainingOjectPresent; - if (!adjustDitch) - { - // there is a NWO, check the position - adjustDitch = - !((isDitchPresent) && - (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).X >= - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X) && - (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).X <= - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide).X)); - } - } - // if the NWO is not there or irrelevant and there is a ditch, then adjust it. - if ((adjustDitch) && (isDitchPresent)) - { - int surfacePointIndex = surfaceLine.Geometry.Points.IndexOf(ditchDikeSidePoint); - AdjustForDitchAndOrNonWaterRetainingObjectatPolderSide(phreaticLine, surfacePointIndex); - } - else - { - // if no ditch then the PL1 will continue horizontally until the end of the profile - // another choice could be to let the PL1 go to polderlevel at the end of the profile, but that could be too optimistic for uplift. - // Discussion about this was done between Vastenburg, Knoeff and The. - // After a renewed discussion with Vastenburg, Van der Zwan and Bka, it has been decided that the PL1 should follow the - // surfaceline (with offset) until either end of surface line or polder level. Note: this is only needed when the phreatic level - // at dike toe is above polder level. - if ((!isNonWaterRetainingOjectPresent) && (!isDitchPresent)) - { - if (phreaticLine.Points[phreaticLine.Points.Count - 1].Z > WaterLevelPolder) - { - AddPhreaticLineAlongSurfaceLevel(phreaticLine); - } - } - } - - //Validate if endpoint surface has reached - if (phreaticLine.Points.Last().X != maxXCoordinateSurface) - { - PLLinePoint endPoint = new PLLinePoint(maxXCoordinateSurface, phreaticLine.Points.Last().Z); - phreaticLine.Points.Add(endPoint); - } - } - - private void AddPhreaticLineAlongSurfaceLevel(PLLine phreaticLine) - { - // Add phreatic point at offset below every surface line point as long as depth > polder level. Else determine the - // proper position of the point at polder level (intersection) and stop. - var surfacePointIndex = surfaceLine.Geometry.Points.IndexOf(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder)) + 1; - bool intersected = false; - for (int i = surfacePointIndex; i < surfaceLine.Geometry.Points.Count; i++) - { - double z = Math.Max(waterLevelPolder, surfaceLine.Geometry.Points[i].Z - PlLineOffsetBelowDikeToeAtPolder); - double x = surfaceLine.Geometry.Points[i].X; - if (waterLevelPolder > surfaceLine.Geometry.Points[i].Z - PlLineOffsetBelowDikeToeAtPolder) - { - // Determine intersection between would be phreatic segment and polderlevel. Add that as next point. - Line waterLevelPolderLine = new Line(new GeometryPoint(surfaceLine.Geometry.Points.First().X, 0, WaterLevelPolder), - new GeometryPoint(surfaceLine.Geometry.Points.Last().X, 0, WaterLevelPolder)); - Line slopeLine = new Line(new GeometryPoint(phreaticLine.Points[phreaticLine.Points.Count - 1].X, 0, phreaticLine.Points[phreaticLine.Points.Count - 1].Z), - new GeometryPoint(surfaceLine.Geometry.Points[i].X, 0, surfaceLine.Geometry.Points[i].Z - PlLineOffsetBelowDikeToeAtPolder)); - GeometryPoint intersectionPoint = new GeometryPoint(); - if (waterLevelPolderLine.IntersectsZ(slopeLine, out intersectionPoint)) - { - x = intersectionPoint.X; - } - intersected = true; - } - PLLinePoint point = new PLLinePoint(x, z); - phreaticLine.Points.Add(point); - if (intersected) - { - break; - } - } - } - private void AdjustForDitchAndOrNonWaterRetainingObjectatPolderSide(PLLine phreaticLine, int surfacePointIndex) { const double maxDouble = 99999.999; - var phreaticPolderPartialLine = new Deltares.Geometry.Line(); + var phreaticPolderPartialLine = new Line(); //#bka: hier niet langer ook starten met waterlevel als waterlevel onder bottomditch zit! - phreaticPolderPartialLine.SetBeginAndEndPoints(new GeometryPoint(phreaticLine.Points[0].X, 0, waterLevelPolder), - new GeometryPoint(maxDouble, 0, waterLevelPolder)); + phreaticPolderPartialLine.SetBeginAndEndPoints(new Point2D(phreaticLine.Points[0].X, waterLevelPolder), + new Point2D(maxDouble, waterLevelPolder)); AddIntersectionDitchDikeSegmentPolderLevelToPhreatic(phreaticLine, surfacePointIndex, phreaticPolderPartialLine); AddIntersectionDitchPolderSegmentPolderLevelToPhreatic(phreaticLine, phreaticPolderPartialLine); } @@ -1864,16 +1865,17 @@ /// /// /// - private void AddIntersectionDitchPolderSegmentPolderLevelToPhreatic(PLLine phreaticLine, Deltares.Geometry.Line phreaticPolderPartialLine) + private void AddIntersectionDitchPolderSegmentPolderLevelToPhreatic(PLLine phreaticLine, Line phreaticPolderPartialLine) { GeometryPoint pointDitchPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); if (pointDitchPolder != null) { int indexatDitchPolder = surfaceLine.Geometry.Points.IndexOf(pointDitchPolder); - var lineDitchPolderSide = new Deltares.Geometry.Line(); + var lineDitchPolderSide = new Line(); if (indexatDitchPolder > 1) { - lineDitchPolderSide.SetBeginAndEndPoints(new GeometryPoint(surfaceLine.Geometry.Points[indexatDitchPolder - 1].X, 0, surfaceLine.Geometry.Points[indexatDitchPolder - 1].Z), new GeometryPoint(surfaceLine.Geometry.Points[indexatDitchPolder].X, 0, surfaceLine.Geometry.Points[indexatDitchPolder].Z)); + lineDitchPolderSide.SetBeginAndEndPoints(new Point2D(surfaceLine.Geometry.Points[indexatDitchPolder - 1].X, surfaceLine.Geometry.Points[indexatDitchPolder - 1].Z), + new Point2D(surfaceLine.Geometry.Points[indexatDitchPolder].X, surfaceLine.Geometry.Points[indexatDitchPolder].Z)); GeometryPoint intersectDitchPolderPhreatic = new GeometryPoint(); if (LineHelper.GetStrictIntersectionPoint(lineDitchPolderSide, phreaticPolderPartialLine, ref intersectDitchPolderPhreatic)) @@ -1899,12 +1901,13 @@ /// /// /// - private void AddIntersectionDitchDikeSegmentPolderLevelToPhreatic(PLLine phreaticLine, int surfacePointIndex, Deltares.Geometry.Line phreaticPolderPartialLine) + private void AddIntersectionDitchDikeSegmentPolderLevelToPhreatic(PLLine phreaticLine, int surfacePointIndex, Line phreaticPolderPartialLine) { if (surfacePointIndex + 1 < surfaceLine.Geometry.Points.Count) { - var lineDitchDikeSide = new Deltares.Geometry.Line(); - lineDitchDikeSide.SetBeginAndEndPoints(new GeometryPoint(surfaceLine.Geometry.Points[surfacePointIndex].X, 0, surfaceLine.Geometry.Points[surfacePointIndex].Z), new GeometryPoint(surfaceLine.Geometry.Points[surfacePointIndex + 1].X, 0, surfaceLine.Geometry.Points[surfacePointIndex + 1].Z)); + var lineDitchDikeSide = new Line(); + lineDitchDikeSide.SetBeginAndEndPoints(new Point2D(surfaceLine.Geometry.Points[surfacePointIndex].X, surfaceLine.Geometry.Points[surfacePointIndex].Z), + new Point2D(surfaceLine.Geometry.Points[surfacePointIndex + 1].X, surfaceLine.Geometry.Points[surfacePointIndex + 1].Z)); GeometryPoint intersectDitchDikePhreatic = new GeometryPoint(); if (LineHelper.GetStrictIntersectionPoint(lineDitchDikeSide, phreaticPolderPartialLine, ref intersectDitchDikePhreatic)) @@ -1944,10 +1947,11 @@ private PLLinePoint DetermineIntersectionBetweenPolderLevelAndDike(double polderLevel) { - var polderlevelLine = new Deltares.Geometry.Line(); + var polderlevelLine = new Line(); double startXCoordinate = this.surfaceLine.Geometry.Points.OrderBy(p => p.X).First().X; GeometryPoint pointEndOfprofile = SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside); - polderlevelLine.SetBeginAndEndPoints(new GeometryPoint(startXCoordinate, 0, polderLevel), new GeometryPoint(pointEndOfprofile.X, 0, polderLevel)); + polderlevelLine.SetBeginAndEndPoints(new Point2D(startXCoordinate, polderLevel), + new Point2D(pointEndOfprofile.X, polderLevel)); ThrowWhenWaterLevelAboveDike(polderLevel, SurfaceLine); @@ -1957,8 +1961,9 @@ endPosition = SurfaceLine.Geometry.Points.IndexOf(SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder)); for (int surfacePointIndex = startPosition; surfacePointIndex < endPosition; surfacePointIndex++) { - var surfaceLineSegment = new Deltares.Geometry.Line(); - surfaceLineSegment.SetBeginAndEndPoints(new GeometryPoint(SurfaceLine.Geometry.Points[surfacePointIndex].X, 0, SurfaceLine.Geometry.Points[surfacePointIndex].Z), new GeometryPoint(SurfaceLine.Geometry.Points[surfacePointIndex + 1].X, 0, SurfaceLine.Geometry.Points[surfacePointIndex + 1].Z)); + var surfaceLineSegment = new Line(); + surfaceLineSegment.SetBeginAndEndPoints(new Point2D(SurfaceLine.Geometry.Points[surfacePointIndex].X, SurfaceLine.Geometry.Points[surfacePointIndex].Z), + new Point2D(SurfaceLine.Geometry.Points[surfacePointIndex + 1].X, SurfaceLine.Geometry.Points[surfacePointIndex + 1].Z)); GeometryPoint intersectPoint = new GeometryPoint(); if (LineHelper.GetStrictIntersectionPoint(surfaceLineSegment, polderlevelLine, ref intersectPoint)) { @@ -1989,15 +1994,22 @@ bool foundIntersect = false; for (int phreaticPointIndex = 0; phreaticPointIndex < phreaticLine.Points.Count - 1; phreaticPointIndex++) { - var phreaticLineSegment = new Deltares.Geometry.Line(); - phreaticLineSegment.SetBeginAndEndPoints(phreaticLine.Points[phreaticPointIndex], phreaticLine.Points[phreaticPointIndex + 1]); + var phreaticLineSegment = new Line(); + phreaticLineSegment.SetBeginAndEndPoints( + new Point2D(phreaticLine.Points[phreaticPointIndex].X, phreaticLine.Points[phreaticPointIndex].Z), + new Point2D(phreaticLine.Points[phreaticPointIndex + 1].X, phreaticLine.Points[phreaticPointIndex + 1].Z)); for (int surfacePointIndex = startIndex; surfacePointIndex < stopIndex; surfacePointIndex++) { - var surfaceLineSegment = new Deltares.Geometry.Line(); - surfaceLineSegment.SetBeginAndEndPoints(SurfaceLine.Geometry.Points[surfacePointIndex], SurfaceLine.Geometry.Points[surfacePointIndex + 1]); - GeometryPoint intersectPoint = new GeometryPoint(); - if (LineHelper.GetStrictIntersectionPoint(phreaticLineSegment, surfaceLineSegment, ref intersectPoint)) + var surfaceLineSegment = new Line(); + surfaceLineSegment.SetBeginAndEndPoints( + new Point2D(SurfaceLine.Geometry.Points[surfacePointIndex].X, SurfaceLine.Geometry.Points[surfacePointIndex].Z), + new Point2D(SurfaceLine.Geometry.Points[surfacePointIndex + 1].X, SurfaceLine.Geometry.Points[surfacePointIndex + 1].Z)); + var intersectGeoPoint = new GeometryPoint(); + var intersectPoint = new Point2D(); + if (LineHelper.GetStrictIntersectionPoint(phreaticLineSegment, surfaceLineSegment, ref intersectGeoPoint)) { + intersectPoint.X = intersectGeoPoint.X; + intersectPoint.Z = intersectGeoPoint.Z; // Prevent any adding when intersectPoint is already on Pl if (!intersectPoint.LocationEquals(phreaticLineSegment.BeginPoint) && !intersectPoint.LocationEquals(phreaticLineSegment.EndPoint)) @@ -2104,15 +2116,15 @@ { CreatePhreaticLineSegmentsInsideDikeForHighRiverLevel(phreaticLine); } - CreatePhreaticLineSegmentsInShoulderAndPolder(phreaticLine); + //CreatePhreaticLineSegmentsInShoulderAndPolder(phreaticLine); ##Bka //Check if phreatic line is above ValidatePhreaticAboveWaterLevelPolder(phreaticLine); //Check if phreatic line is below the surface line ValidatePhreaticBelowDike(phreaticLine); // currentPL1Line is needed when calculating uplift reduction for PL3 and Pl4 - AdaptPL1ForNonWaterRetainingObject(ref phreaticLine); + //AdaptPL1ForNonWaterRetainingObject(ref phreaticLine); ##Bka currentPL1Line = phreaticLine; return phreaticLine; } Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/Parallel.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/Parallel.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/Parallel.cs (revision 330) @@ -0,0 +1,306 @@ +// 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.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using Deltares.DamEngine.Data.Standard.Calculation; +//using Deltares.Standard.Logging; +using ThreadState = System.Threading.ThreadState; + +namespace Deltares.DamEngine.Calculators.General +{ + /// + /// Utility to run tasks in parallel + /// + public class Parallel + { + private static Queue queue = new Queue(); + private static TaskDelegate task = null; + private static ProgressDelegate progress = null; + private static int total = 0; + private static int executed = 0; + private static List threads = new List(); + private static List processes = new List(); + private static bool stopPressed = false; + private static bool errorOccured = false; + private static bool limitToAvailableProcessors = true; + + /// + /// Runs a number of tasks in parallel. Returns when all tasks have been executed. + /// + /// The objects on which the task is to be performed + /// The task to be executed + public static void Run(IList list, TaskDelegate parallelTask) + { + Run(list, parallelTask, null, -1); + } + + /// + /// Runs a number of tasks in parallel. Returns when all tasks have been executed. + /// + /// The objects on which the task is to be performed + /// The task to be executed + /// The maximum number of processes, will be equal to the number of cores if omitted + public static void Run(IList list, TaskDelegate parallelTask, int maxProcesses) + { + Run(list, parallelTask, null, maxProcesses); + } + + /// + /// Runs a number of tasks in parallel. Returns when all tasks have been executed. + /// + /// The objects on which the task is to be performed + /// The task to be executed + /// Optional delegate indicating the progress of the tasks + public static void Run(IList list, TaskDelegate parallelTask, ProgressDelegate progress) + { + Run(list, parallelTask, progress, -1); + } + + /// + /// Runs a number of tasks in parallel. Returns when all tasks have been executed. + /// + /// The objects on which the task is to be performed + /// The task to be executed + /// The maximum number of processes, will be equal to the number of cores if omitted + /// Optional delegate indicating the progress of the tasks + public static void Run(IList list, TaskDelegate parallelTask, ProgressDelegate progressDelegate, int maxProcesses) + { + if (list.Count == 0) + { + return; + } + + stopPressed = false; + processes.Clear(); + + if (maxProcesses <= 0) + { + maxProcesses = Int32.MaxValue; + } + + maxProcesses = Math.Min(list.Count, maxProcesses); + + if (limitToAvailableProcessors) + { + maxProcesses = Math.Min(Environment.ProcessorCount, maxProcesses); + } + + //DateTime start = DateTime.Now; + + if (progressDelegate != null) + { + progressDelegate(0); + } + + if (maxProcesses == 1) + { + total = list.Count; + RunSequential(list, parallelTask, progressDelegate); + } + else + { + try + { + queue.Clear(); + task = parallelTask; + progress = progressDelegate; + + foreach (var argument in list) + { + queue.Enqueue(argument); + } + + total = queue.Count; + executed = 0; + + threads.Clear(); + for (int i = 0; i < maxProcesses; i++) + { + var thread = new Thread(RunTask); + threads.Add(thread); + + thread.Start(Context.CurrentContext); // Pass the current context as task context + } + + foreach (var thread in threads) + { + thread.Join(); + } + } + catch (ThreadAbortException) + { + Abort(); + } + } + + if (errorOccured) + { + throw new Exception("Error occured in one of the parallel runs."); + } + //DateTime end = DateTime.Now; + //TimeSpan period = end - start; + + //if (period.TotalMilliseconds > 0) + //{ + // string msg = (maxProcesses == 1 ? "Duration of tasks: " : "Parallel duration: "); + // Console.WriteLine(msg + period.TotalMilliseconds + " ms"); + //} + } + + /// + /// Kills all running and queued tasks + /// + public static void Abort() + { + stopPressed = true; + + foreach (var process in processes.ToArray()) + { + if (!process.HasExited) + { + process.Kill(); + } + } + + foreach (var thread in threads) + { + switch (thread.ThreadState) + { + case ThreadState.Running: + try + { + thread.Abort(); + } + catch (ThreadAbortException) + { + // ignore + } + break; + case ThreadState.WaitSleepJoin: + thread.Interrupt(); + break; + } + } + + threads.Clear(); + processes.Clear(); + } + + /// + /// Registers a process which should be killed too when the method is called + /// + /// The process + public static void KillOnAbort(Process process) + { + processes.Add(process); + } + + private static void RunSequential(IList list, TaskDelegate parallelTask, ProgressDelegate progressDelegate) + { + for (int i = 0; i < list.Count; i++) + { + parallelTask(list[i]); + + if (progressDelegate != null) + { + progressDelegate(Convert.ToDouble(i + 1)/Convert.ToDouble(total)); + } + } + } + + private static void RunTask(object context) + { + object argument = null; + + // Set the context of the task thread + Context.CurrentContext = context as IContext; + + while (true) + { + lock (queue) + { + if (!stopPressed && queue.Count > 0) + { + argument = queue.Dequeue(); + } + else + { + return; + } + } + + try + { + if (!stopPressed) + { + task(argument); + } + } + catch (ThreadAbortException) + { + stopPressed = true; + } + catch (Exception e) + { + // most errors already reported to logfile + while (e != null) // Extra instrumentation to trace errors occurring during parallel executions + { +// LogManager.Add(new LogMessage(LogMessageType.Trace, task, "Exception occurred in parallel run: " + e.Message + Environment.NewLine + +// "Stacktrace: " + Environment.NewLine +// + e.StackTrace)); ##BKA: replace with some other mechanism!? + e = e.InnerException; + } + errorOccured = true; + return; + } + finally + { + if (progress != null && !stopPressed) + { + lock (queue) + { + progress(Convert.ToDouble(++executed)/Convert.ToDouble(total)); + } + } + } + } + } + + /// + /// Indicates whether the number of parallel processes is limited to the number of available cores + /// + public static bool LimitToAvailableProcessors + { + get + { + return limitToAvailableProcessors; + } + set + { + limitToAvailableProcessors = value; + } + } + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Interfaces/DGSDAMSlopeWInterface.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Interfaces/DGSDAMSlopeWInterface.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Interfaces/DGSDAMSlopeWInterface.cs (revision 330) @@ -0,0 +1,70 @@ +// 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.Runtime.InteropServices; + +namespace Deltares.DamEngine.Calculators.Interfaces +{ + public class DGSDAMSlopeWInterface : DgsStandardDllInterface + { + private const string DllFileName = @"DGSDAMSlopeW.dll"; + + [DllImport(DllFileName)] + static extern int DllGetVersion(out DllVersionInfoStructure dllVersionInfoStructure); + [DllImport(DllFileName)] + static extern string GetDescription(); + [DllImport(DllFileName)] + static extern string GetErrorMessage(); + [DllImport(DllFileName)] + static extern int CreateSlopeWProject(string inputXmlString); + + /// + /// GetDllVersion + /// + /// version as string + new public string GetDllVersion() + { + DllVersionInfoStructure dllInfo; + var returnValue = DllGetVersion(out dllInfo); + return dllInfo.DwBuildNumber.ToString(); + } + + /// + /// CreateProjectFile + /// + /// Error number + public int CreateProjectFile(string inputXmlString) + { + return (CreateSlopeWProject(inputXmlString)); + } + + /// + /// ErrorMessage + /// + /// Error as string + new public string ErrorMessage() + { + return (GetErrorMessage()); + } + + + } +} Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/MStabProject.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/MStabProject.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/MStabProject.cs (revision 330) @@ -0,0 +1,448 @@ +// 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.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Net.Mime; +using System.Xml.Serialization; +using Deltares.DamEngine.Data.Geometry; +using Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.Data.Standard; +using Deltares.DamEngine.Data.Standard.Calculation; +using Deltares.DamEngine.Data.Standard.Language; +using Deltares.DamEngine.Data.Standard.Logging; +using Deltares.DamEngine.Data.Standard.Validation; +//using XmlSerializer = Deltares.Standard.IO.Xml.XmlSerializer; + +namespace Deltares.DamEngine.Calculators.Stability +{ + public class MStabProject : ICloneable, IDisposable + { + public MStabProject Clone() + { + throw new NotImplementedException(); + } + + public void Dispose() + { + throw new NotImplementedException(); + } + } + +// public class MStabProject : Project, ICloneable, IDisposable +// { +// public bool IsApplicationCreated; +// private List messages = new List(); +// +// private string originalStiFileName; +// private CalculationResult result = CalculationResult.NoRun; +// private StabilityModel stabilityModel; //Object of DefinitionModel +// +// public Func GetGeometryImage; +// +// //public MStabProject(ICoordinateSystem coordinateSystem) +// public MStabProject() +// { +// originalStiFileName = ""; +// +// Stability = new StabilityModel(); +// +// DataEventPublisher.OnAfterChange += DataEventPublisher_OnAfterChange; +// } +// +// +// [Label("GeometryPicture")] +// [Description("GeometryPicture")] +// public MediaTypeNames.Image GeometryPicture +// { +// get +// { +// return GetGeometryImage(); +// } +// } +// +// [XmlCategory("Identification")] +// public string OriginalStiFileName +// { +// get +// { +// return originalStiFileName; +// } +// set +// { +// originalStiFileName = value; +// } +// } +// +// /// +// /// //Object of SoilModel +// /// +// [XmlCategory("Input")] +// [XmlElement("Soils")] +// [Validate] +// public SoilModel SoilModel +// { +// get +// { +// return stabilityModel.SoilModel; +// } +// } +// +// /// +// /// Object of GeometryData +// /// +// [XmlCategory("Input")] +// public GeometryData Geometry +// { +// get +// { +// return stabilityModel != null && stabilityModel.SoilProfile != null ? stabilityModel.SoilProfile.Geometry : null; +// } +// } +// +// /// +// /// Object of WaternetData +// /// +// [XmlCategory("Input")] +// [XmlElement("WaternetData")] +// public GeotechnicsModel Geotechnics +// { +// get +// { +// return stabilityModel.GeotechnicsData; +// } +// } +// +// /// +// /// Object of DefinitionModel +// /// +// [XmlCategory("Input")] +// [XmlElement("Definitions")] +// [Validate] +// public StabilityModel Stability +// { +// get +// { +// return stabilityModel; +// } +// set +// { +// if (stabilityModel != null && !ReferenceEquals(stabilityModel, value) && +// value != null) // Hack: StabilityCalculation sets this property to null so it can claim owner ship of StabilityModel +// { +// Stability.Dispose(); +// } +// stabilityModel = value; +// +// Soil.SoilPropertyManager = stabilityModel; +// } +// } +// +// public void SetStabilityModel(StabilityModel newStabilityModel) +// { +// stabilityModel = newStabilityModel; +// +// Soil.SoilPropertyManager = stabilityModel; +// } +// +// /// +// /// Units manager object +// /// +// [XmlCategory("Input")] +// public UnitsManager Units +// { +// get +// { +// return UnitsManager.Units; +// } +// } +// +// [XmlCategory("Output")] +// public CalculationResult Result +// { +// get +// { +// return result; +// } +// set +// { +// if (result != value) +// { +// DataEventPublisher.BeforeChange(this, "Result"); +// result = value; +// DataEventPublisher.AfterChange(this, "Result"); +// } +// } +// } +// +// [XmlCategory("Output")] +// [Impact(Impact.Descriptive)] +// [XmlIgnore] +// public SlidingModel SlidingData +// { +// get +// { +// return stabilityModel != null ? stabilityModel.SlidingModel : null; +// } +// set +// { +// if (stabilityModel != null) +// { +// if (value != stabilityModel.SlidingModel) +// { +// DataEventPublisher.BeforeChange(this, "SlidingData"); +// +// stabilityModel.SlidingModel = value; +// +// if (stabilityModel.SlidingModel == null) +// { +// Result = CalculationResult.NoRun; +// } +// +// DataEventPublisher.AfterChange(this, "SlidingCurve"); // to force update in UI +// DataEventPublisher.AfterChange(this, "SlidingData"); +// DataEventPublisher.AfterChange(this, "RestProfile"); +// DataEventPublisher.AfterChange(this, "SafeProfile"); +// } +// } +// } +// } +// +// [XmlIgnore] +// [Browsable(false)] +// [Impact(Impact.None)] +// public SlidingCurve SlidingCurve +// { +// get +// { +// return SlidingData != null ? MinimumSafetyCurve : null; +// } +// } +// +// [Impact(Impact.None)] +// public RestProfile RestProfile +// { +// get +// { +// return SlidingData != null ? SlidingData.RestProfile : null; +// } +// } +// +// [Impact(Impact.None)] +// public SafeProfile SafeProfile +// { +// get +// { +// return SlidingData != null ? SlidingData.SafeProfile : null; +// } +// } +// +// [XmlIgnore] +// [ReadOnly(true)] +// [Translation("Slices")] +// public IList MinimumSafetySlices +// { +// get +// { +// if (SlidingData != null && SlidingData.CurrentZone != null && MinimumSafetyCurve != null) +// { +// return MinimumSafetyCurve.Slices; +// } +// else +// { +// return new List(); +// } +// } +// } +// +// [Validate] +// public IGeometryModel GeometryDataModel +// { +// get +// { +// return Geometry; +// } +// } +// +// [Validate] +// public IGeometryModel WaternetDataModel +// { +// get +// { +// return stabilityModel.GeotechnicsData; +// } +// } +// +// public List Messages +// { +// get +// { +// return messages; +// } +// } +// +// public List GetMStabModels() +// { +// var models = new List() +// { +// this, Geometry, SoilModel, WaternetDataModel, +// stabilityModel, stabilityModel.ConsolidationMatrix, SlidingData +// }; +// +// return models; +// } +// +// public void ProcessResults(string inputString) +// { +// var deserializer = new XmlDeserializer(); +// try +// { +// MStabProject newProject = null; +// DataEventPublisher.InvokeWithoutPublishingEvents(() => { newProject = (MStabProject)deserializer.XmlDeserializeFromString(inputString, typeof(MStabProject)); }); +// +// SlidingData = newProject.SlidingData; +// newProject.Dispose(); +// } +// catch { } +// } +// +// public IEnumerable[] GetModelComponents() +// { +// var lists = new List(); +// lists.Add(Geometry.Points); +// lists.Add(Geometry.Curves); +// lists.AddRange(stabilityModel.GetModelLists()); +// +// return lists.ToArray(); +// } +// +// /// +// /// Update object counters +// /// +// public void UpdateCounters() +// { +// Geometry.UpdateCounters(); +// stabilityModel.UpdateCounters(); +// stabilityModel.GeotechnicsData.UpdateCounters(); +// SoilModel.UpdateCounters(); +// } +// +// /// +// /// Create Default Library Data +// /// +// public void CreateDefaultLibraryData() +// { +// SoilModel.CreateDefaultSoilLibrary(); +// } +// +// /// +// /// Renumbers the geometry items +// /// +// public void RenumberGeometryObjects() +// { +// UndoRedoManager.Instance.BeginAction(); +// // Renumbers all Geometry Points as well +// GeometryDataModel.RenumberGeometryObjects(); +// stabilityModel.RenumberGeometryObjects(); +// DataEventPublisher.Changed(this, "Renumbering"); +// DataEventPublisher.DoRefreshView(null); +// UndoRedoManager.Instance.EndAction(); +// } +// +// #region IVisibleEnabled Members +// +// public override bool IsVisible(string property) +// { +// switch (property) +// { +// case "RestProfile": +// case "SafeProfile": +// case "SlidingCurve": +// return SlidingData != null; +// case "MinimumSafetySlices": +// return SlidingData != null && SlidingData.CurrentZone != null && MinimumSafetyCurve != null; +// default: +// return base.IsVisible(property); +// } +// } +// +// #endregion +// +// public MStabProject Clone() +// { +// MStabProject clone = default(MStabProject); +// DataEventPublisher.InvokeWithoutPublishingEvents(() => +// { +// string xml = new XmlSerializer().SerializeToString(this); +// clone = new XmlDeserializer().XmlDeserializeFromString(xml); +// }); +// return clone; +// } +// +// public void Dispose() +// { +// DataEventPublisher.OnAfterChange -= DataEventPublisher_OnAfterChange; +// +// if (Stability != null) +// { +// Stability.Dispose(); +// //Stability = null; +// } +// } +// +// private SlidingCurve MinimumSafetyCurve +// { +// get +// { +// return SlidingData.CurrentZone.MinimumSafetyCurve; +// } +// } +// +// private void DataEventPublisher_OnAfterChange(object sender, PublishEventArgs e) +// { +// if (HasComputationImpact(sender, e.Property)) +// { +// if (!UndoRedoManager.Instance.IsUndoingRedoing) +// { +// SlidingData = null; +// } +// } +// +// if (string.IsNullOrWhiteSpace(e.Property)) +// { +// return; +// } +// +// var slidingData = sender as SlidingModel; +// if (slidingData != null && e.Property == "CurrentZone") +// { +// DataEventPublisher.AfterChange(this, x => x.SlidingCurve); +// } +// } +// +// private static bool HasComputationImpact(object sender, string property) +// { +// return property != null && PropertyInfoSupport.GetPropertyInfo(sender.GetType(), property).GetImpact(sender) == Impact.Computation; +// } +// } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Uplift/SoilVolumicMassCalculator.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Uplift/SoilVolumicMassCalculator.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Uplift/SoilVolumicMassCalculator.cs (revision 330) @@ -0,0 +1,343 @@ +// 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.Collections.Generic; +using System.Linq; +using Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.Data.Standard; + +namespace Deltares.DamEngine.Calculators.Uplift +{ + /// + /// Exception class for SoilVolumicMassCalculator + /// + public class SoilVolumicMassCalculatorException : Exception + { + public SoilVolumicMassCalculatorException(string message) : base(message) {} + } + + /// + /// Calculation class to determine weight of the soil between TopOfLayerToBeEvaluated and SurfaceLevel + /// + public class SoilVolumicMassCalculator + { + private const double CTolerance = 0.00000001; + + /// + /// Initializes a new instance of the class. + /// + public SoilVolumicMassCalculator() + { + VolumicWeightOfWater = 9.81; + IsUseOvenDryUnitWeight = false; + } + + public bool IsUseOvenDryUnitWeight { get; set; } + public double VolumicWeightOfWater { get; set; } + public double PhreaticLevel { get; set; } + public double SurfaceLevel { get; set; } + public double TopOfLayerToBeEvaluated { get; set; } + public SoilProfile1D SoilProfile { get; set; } + public double MinimumThicknessCoverLayer { get; set; } + + /// + /// Calculates the total weight of the soil between SurfaceLevel and TopOfLayerToBeEvaluated, + /// taking into account whether the soil is submerged or not + /// + /// total mass + public double CalculateTotalMass() + { + ThrowWhenSoilProfileIsNull(); + ThrowWhenSurfaceLevelNotInsideProfile(); + ThrowWhenTopLayerToBeEvaluatedNotInsideProfile(); + + var weight = SoilProfile.Layers + .Where(layer => layer.TopLevel > TopOfLayerToBeEvaluated) + .Sum(layer => GetWeight(layer)); + + // Is there water above the soil layer? If so add the volumic weight + // of water to the soil mass + if (PhreaticLevel > SurfaceLevel) + { + var height = PhreaticLevel - SurfaceLevel; + weight += height*VolumicWeightOfWater; + } + + return weight; + } + + /// + /// Calculates the effective stress of the soil between TopOfLayerToBeEvaluated and SurfaceLevel + /// + /// + public double CalculateEffectiveStress() + { + ThrowWhenSoilProfileIsNull(); + ThrowWhenSoilProfileHasNoLayers(); + ThrowWhenSurfaceLevelNotInsideProfile(); + ThrowWhenTopLayerToBeEvaluatedNotInsideProfile(); + var involvedLayers = SoilProfile.Layers.Where(layer => layer.TopLevel > TopOfLayerToBeEvaluated); + var weight = involvedLayers.Sum(layer => GetEffectiveStress(layer)); + // Check to see if thickness of all involved layers is is smaller than the given minimum thickness. If so, + // then add the weight of the "missing" soil(s) by multipliying the difference by the weight of the toplevel. + // Using the weight of the toplevel might be theoreticaly incorrect but this is a good and simple approach + // which has been accorded by Erik Vastenburg. + var thicknessInvolvedLayers = involvedLayers.Sum(layer => GetLayerHeight(layer)); + if (thicknessInvolvedLayers < MinimumThicknessCoverLayer) + { + Soil soil = involvedLayers.First().Soil; + double bottomLevel = Math.Min(involvedLayers.First().TopLevel, SurfaceLevel); + double height = MinimumThicknessCoverLayer - thicknessInvolvedLayers; + double topLevel = bottomLevel + height; + double factorWet; + double factorDry; + DetermineHeightAndDryAndWetFraction(topLevel, bottomLevel, out factorWet, out factorDry); + weight += GetSoilUnitWeightDry(soil).Value*factorDry*height + (soil.BelowPhreaticLevel - VolumicWeightOfWater)*factorWet*height; + } + return weight; + } + + /// + /// Validates the input + /// + /// a filled list when errors are found else an empty list + public List Validate() + { + var errors = new List(); + if (SoilProfile == null) + { + errors.Add("The soilprofile is not defined"); + return errors; + } + if ((SurfaceLevel - SoilProfile.TopLevel) > CTolerance || (SurfaceLevel - SoilProfile.BottomLevel) < -CTolerance) + { + errors.Add("Surfacelevel is not inside soil profile"); + } + errors.AddRange(from soilLayer1D in SoilProfile.Layers + where soilLayer1D.Soil == null + select "The soil material in the layer could not be converted to local type"); + if ((TopOfLayerToBeEvaluated - SoilProfile.TopLevel) > CTolerance || + (TopOfLayerToBeEvaluated - SoilProfile.BottomLevel) < -CTolerance) + { + errors.Add("The top layer to be evaluated is not inside the soil profile"); + } + return errors; + } + + /// + /// Gets the contribution of the weight of a layer, taking in account the phreatic level + /// + /// The layer. + /// + private double GetWeight(SoilLayer1D layer) + { + var soil = layer.Soil as Soil; + ThrowWhenSoilIsNull(soil); + + double topLevel, bottomLevel; + double height = GetLayerHeight(layer, out topLevel, out bottomLevel); + double factorWet; + double factorDry; + DetermineHeightAndDryAndWetFraction(topLevel, bottomLevel, out factorWet, out factorDry); + + return GetSoilUnitWeightDry(soil).Value*factorDry*height + soil.BelowPhreaticLevel*factorWet*height; + } + + /// + /// Gets the contribution to the effective stress of a layer, taking in account the phreatic level + /// + /// The layer. + /// + private double GetEffectiveStress(SoilLayer1D layer) + { + var soil = layer.Soil as Soil; + ThrowWhenSoilIsNull(soil); + + double topLevel, bottomLevel; + double height = GetLayerHeight(layer, out topLevel, out bottomLevel); + double factorWet; + double factorDry; + DetermineHeightAndDryAndWetFraction(topLevel, bottomLevel, out factorWet, out factorDry); + + // If above phreatic line use the dry weight of the soil + // if below phreatic line use the effective submerged weight (gamma_sat - gamma_water) + return GetSoilUnitWeightDry(soil).Value*factorDry*height + (soil.BelowPhreaticLevel - VolumicWeightOfWater)*factorWet*height; + } + + /// + /// Determines the height and dry and wet fraction of the layer. + /// + /// The layer. + /// The height. + /// The factor wet. + /// The factor dry. + private void DetermineHeightAndDryAndWetFraction(double topLevel, double bottomLevel, out double factorWet, out double factorDry) + { + double height = topLevel - bottomLevel; + factorWet = 0.0; + factorDry = 0.0; + + if (topLevel < PhreaticLevel || topLevel.AlmostEquals(PhreaticLevel)) + { + factorWet = 1.0; + } + else if (bottomLevel > PhreaticLevel || bottomLevel.AlmostEquals(PhreaticLevel)) + { + factorDry = 1.0; + } + else + { + var pLevel = (topLevel - PhreaticLevel); + factorDry = pLevel.AlmostEquals(0.0) ? 0.0 : pLevel/height; + factorWet = 1.0 - factorDry; + } + } + + /// + /// Calculates the height of a layer taking into account the surfacelevel and the TopOfLayerToBeEvaluated + /// + /// + /// + private double GetLayerHeight(SoilLayer1D layer) + { + var layerHeight = SoilProfile.GetLayerHeight(layer); + double topLevel; + if (layer.TopLevel > SurfaceLevel) + { + topLevel = SurfaceLevel; + layerHeight = Math.Max(layerHeight - (layer.TopLevel - SurfaceLevel), 0); + } + else + { + topLevel = layer.TopLevel; + } + + double bottomLevel = topLevel - layerHeight; + bottomLevel = bottomLevel > TopOfLayerToBeEvaluated ? bottomLevel : TopOfLayerToBeEvaluated; + return topLevel - bottomLevel; + } + + /// + /// Gets the soil dry unit weight. + /// + /// The soil. + /// + private double? GetSoilUnitWeightDry(Soil soil) + { + if (IsUseOvenDryUnitWeight) + { + return soil.DryUnitWeight; + } + else + { + return soil.AbovePhreaticLevel; + } + } + + /// + /// Gets the height of the layer. + /// + /// The layer. + /// The top level. + /// The bottom level. + /// + private double GetLayerHeight(SoilLayer1D layer, out double topLevel, out double bottomLevel) + { + var layerHeight = SoilProfile.GetLayerHeight(layer); + if (layer.TopLevel > SurfaceLevel) + { + topLevel = SurfaceLevel; + layerHeight = Math.Max(layerHeight - (layer.TopLevel - SurfaceLevel), 0); + } + else + { + topLevel = layer.TopLevel; + } + + bottomLevel = topLevel - layerHeight; + bottomLevel = bottomLevel > TopOfLayerToBeEvaluated ? bottomLevel : TopOfLayerToBeEvaluated; + return topLevel - bottomLevel; + } + + /// + /// Check precondition: Throws the when soil profile is null. + /// + /// The soilprofile is not defined + private void ThrowWhenSoilProfileIsNull() + { + if (SoilProfile == null) + { + throw new SoilVolumicMassCalculatorException("The soilprofile is not defined"); + } + } + + /// + /// Throws the when soil profile has no layers. + /// + /// The soilprofile is not defined + private void ThrowWhenSoilProfileHasNoLayers() + { + if (SoilProfile.LayerCount == 0) + { + throw new SoilVolumicMassCalculatorException("The soilprofile has no layers"); + } + } + + /// + /// Check precondition: Throws the when soil is null. + /// + /// The soil. + /// The soil material in the layer could not be converted to local type + private void ThrowWhenSoilIsNull(Soil soil) + { + if (soil == null) + { + throw new SoilVolumicMassCalculatorException("The soil material in the layer could not be converted to local type"); + } + } + + /// + /// Check precondition: Throws the when surface level is not inside profile. + /// + /// Surfaceline is not inside soil profile + private void ThrowWhenSurfaceLevelNotInsideProfile() + { + if ((SurfaceLevel - SoilProfile.TopLevel) > CTolerance || + (SurfaceLevel - SoilProfile.BottomLevel) < -CTolerance) + { + throw new SoilVolumicMassCalculatorException("Surfacelevel is not inside soil profile"); + } + } + + /// + /// Check precondition: Throws the when top layer to be evaluated is not inside profile. + /// + /// The top layer to be evaluated is not inside the soil profile + private void ThrowWhenTopLayerToBeEvaluatedNotInsideProfile() + { + if ((TopOfLayerToBeEvaluated - SoilProfile.TopLevel) > CTolerance || (TopOfLayerToBeEvaluated - SoilProfile.BottomLevel) < -CTolerance) + { + throw new SoilVolumicMassCalculatorException("The top layer to be evaluated is not inside the soil profile"); + } + } + } +} \ No newline at end of file Fisheye: Tag 330 refers to a dead (removed) revision in file `dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment/RWScenariosCalculation.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryData.cs =================================================================== diff -u -r316 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryData.cs (.../GeometryData.cs) (revision 316) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryData.cs (.../GeometryData.cs) (revision 330) @@ -311,8 +311,8 @@ curveDataList.Clear(); surfaceDataList.Clear(); - newlyEffectedPoints.Clear(); - newlyEffectedCurves.Clear(); +// newlyEffectedPoints.Clear(); +// newlyEffectedCurves.Clear(); } /// /// deletes all the Loop from IGeometryLoop. Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/LineHelper.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/LineHelper.cs (.../LineHelper.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/LineHelper.cs (.../LineHelper.cs) (revision 330) @@ -31,6 +31,31 @@ public static class LineHelper { /// + /// Calculate intersection between two lines (strict interpolation) + /// + /// + /// + /// + /// + public static bool GetStrictIntersectionPoint(Line line1, Line line2, ref GeometryPoint intersectPoint) + { + var point1 = new Point2D(line1.BeginPoint.X, line1.BeginPoint.Z); + var point2 = new Point2D(line1.EndPoint.X, line1.EndPoint.Z); + var point3 = new Point2D(line2.BeginPoint.X, line2.BeginPoint.Z); + var point4 = new Point2D(line2.EndPoint.X, line2.EndPoint.Z); + + Point2D ip; + var res = Routines2D.DetermineIf2DLinesIntersectStrickly(point1.X, point1.Z, point2.X, point2.Z, + point3.X, point3.Z, point4.X, point4.Z, out ip); + if (ip != null) + { + intersectPoint.X = ip.X; + intersectPoint.Z = ip.Z; + } + return res == LineIntersection.Intersects; + } + + /// /// This method uses constant extrapolation from the start point to the negative X direction and /// from the end point to the positive X direction. Then the method tries to find intersection /// points with the circle on that line. @@ -105,5 +130,36 @@ { return Routines2D.IntersectCircleline(xm, ym, r, line.BeginPoint.X, line.EndPoint.X, line.BeginPoint.Z, line.EndPoint.Z); } + + public static GeometryPoint GetIntersectionPointWithExtrapolation(GeometryPoint p1, GeometryPoint p2, GeometryPoint p3, GeometryPoint p4) + { + return IntersectionPointWithExtrapolation(p1, p2, p3, p4); + } + + /// + /// Determines the intersection point of two lines, allowing the intersection point being extrapolated. + /// + /// + /// + /// + /// + /// Intersection point or null (parallel lines) + private static GeometryPoint IntersectionPointWithExtrapolation(GeometryPoint p1, GeometryPoint p2, GeometryPoint p3, GeometryPoint p4) + { + GeometryPoint intersectPoint = null; + + var point1 = new Point2D(p1.X, p1.Z); + var point2 = new Point2D(p2.X, p2.Z); + var point3 = new Point2D(p3.X, p3.Z); + var point4 = new Point2D(p4.X, p4.Z); + + var ip = new Point2D(); + var res = Routines2D.DetermineIf2DLinesIntersectWithExtrapolation(point1, point2, point3, point4, ref ip); + if (ip != null) + { + intersectPoint = new GeometryPoint(ip.X, ip.Z); + } + return intersectPoint; + } } } \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/Context.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/Context.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/Context.cs (revision 330) @@ -0,0 +1,117 @@ +// 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.Collections; + +namespace Deltares.DamEngine.Calculators.General +{ + /// + /// Entry point for the current context + /// + public static class Context + { + [ThreadStatic] + private static IContext currentContext; + + /// + /// Application wide context + /// + public static IContext CurrentContext + { + get + { + return currentContext; + } + set + { + currentContext = value; + } + } + + public static bool? IsVisible(object source, string member) + { + bool? visibility = null; + if (currentContext != null) + { + visibility = currentContext.IsVisible(source, member); + } + return visibility; + } + + public static bool? IsEnabled(object source, string member) + { + bool? enabled = null; + if (currentContext != null) + { + enabled = currentContext.IsEnabled(source, member); + } + return enabled; + } + + public static bool ShouldValidate(object source, string member, bool defaultValidate) + { + if (currentContext == null) + { + return defaultValidate; + } + + bool? validate = currentContext.ShouldValidate(source, member); + return validate.HasValue ? validate.Value : defaultValidate; + } + + public static ICollection GetDomain(object source, string member, ICollection defaultDomain) + { + if (currentContext == null) + { + return defaultDomain; + } + + ICollection domain = currentContext.GetDomain(source, member); + return domain ?? defaultDomain; + } + + public static object GetFormat(Type type, object source, string property) + { + return currentContext != null ? currentContext.GetFormat(type, source, property) : null; + } + + public static int[] GetPropertyOrder(Type type, string property) + { + return currentContext != null ? currentContext.GetPropertyOrder(type, property) : null; + } + + public static double? GetMinimum(object source, string property) + { + return currentContext != null ? currentContext.GetMinimum(source, property) : null; + } + + public static double? GetMaximum(object source, string property) + { + return currentContext != null ? currentContext.GetMaximum(source, property) : null; + } + + public static object GetDefault(Type type, string property) + { + return currentContext != null ? currentContext.GetDefault(type, property) : null; + } + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile1D.cs =================================================================== diff -u -r316 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile1D.cs (.../SoilProfile1D.cs) (revision 316) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile1D.cs (.../SoilProfile1D.cs) (revision 330) @@ -331,6 +331,39 @@ } /// + /// Determines the infiltration layer. + /// + /// Length of the penetration. + public void DetermineInfiltrationLayer(double penetrationLength) + { + SoilLayer1D infiltrationLayer = null; + + SoilLayer1D bottomAquiferLayer = BottomAquiferLayer; + + if (penetrationLength > 0 && bottomAquiferLayer != null) + { + SoilLayer1D inBetweenAquiferLayer = InBetweenAquiferLayer; + + double aquiferBottom = inBetweenAquiferLayer == null ? + Double.PositiveInfinity : inBetweenAquiferLayer.BottomLevel; + + IList infiltrationLayers = + layers.Where(l => l.TopLevel <= aquiferBottom && l.TopLevel > bottomAquiferLayer.TopLevel) + .ToList(); + + if (infiltrationLayers.Count > 0) + { + double separationLevel = bottomAquiferLayer.TopLevel + penetrationLength; + + if (separationLevel <= infiltrationLayers.First().TopLevel) + { + infiltrationLayer = layers.Last(l => l.TopLevel >= separationLevel); + } + } + } + } + + /// /// Validates this instance (using validator mechanism). /// /// Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Routines2D.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Routines2D.cs (.../Routines2D.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Routines2D.cs (.../Routines2D.cs) (revision 330) @@ -67,7 +67,7 @@ /// public static class Routines2D { - private struct LineConstant + public struct LineConstant { public double X; public double Y; @@ -381,6 +381,17 @@ return Math.Abs(CrossProduct(aLine1ConstantX, aLine2ConstantX, aLine1ConstantY, aLine2ConstantY)) < tolerance; } + + public static LineIntersection DetermineIf2DLinesIntersectWithExtrapolation(Point2D aPoint1, Point2D aPoint2, Point2D aPoint3, Point2D aPoint4, ref Point2D aIntersectionPoint) + { + var lLineConstant1 = CalculateNormalLineConstants(aPoint1.X, aPoint1.Z, aPoint2.X, aPoint2.Z); + var lLineConstant2 = CalculateNormalLineConstants(aPoint3.X, aPoint3.Z, aPoint4.X, aPoint4.Z); + + var lResult = DetermineIf2DLinesIntersectWithExtrapolation(lLineConstant1, lLineConstant2, out aIntersectionPoint); + + return lResult; + } + /// /// Finds the Intersection Points for two given 2D Lines. /// The intersection point does not need to be on either given line, extrapolation is used to find it beyond the length of the given lines. @@ -390,7 +401,7 @@ /// /// /// - private static LineIntersection DetermineIf2DLinesIntersectWithExtrapolation(LineConstant aLine1Constant, LineConstant aLine2Constant, out Point2D aIntersectionPoint) + public static LineIntersection DetermineIf2DLinesIntersectWithExtrapolation(LineConstant aLine1Constant, LineConstant aLine2Constant, out Point2D aIntersectionPoint) { aIntersectionPoint = new Point2D(0.0, 0.0); Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs =================================================================== diff -u -r316 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs (.../SurfaceLine2Extensions.cs) (revision 316) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs (.../SurfaceLine2Extensions.cs) (revision 330) @@ -23,6 +23,7 @@ using System.Collections.Generic; using System.Linq; using Deltares.DamEngine.Data.Geometry; +using Deltares.DamEngine.Data.Standard; namespace Deltares.DamEngine.Data.Geotechnics { @@ -134,5 +135,412 @@ IsDefined(line, CharacteristicPointType.DikeTopAtPolder) && IsDefined(line, CharacteristicPointType.DikeToeAtPolder); } + + /// + /// Add 2D characteristic point without a type + /// + /// The surfaceline to be modified. + /// The x. + /// The z. + public static void EnsurePoint(this SurfaceLine2 line, double x, double z) + { + line.EnsurePointOfType(x, z, null); + } + + /// + /// Add characteristic point in X-Z plane + /// + /// The surfaceline to be modified. + /// The x. + /// The z. + /// The type. + public static void EnsurePointOfType(this SurfaceLine2 line, double x, double z, CharacteristicPointType? type) + { + if (!line.CharacteristicPoints.GeometryMustContainPoint) + { + throw new NotImplementedException("SurfaceLine specific method, not implemented for 'Ringtoets'-mode."); + } + + bool movedPointToMatch = false; + bool addPoint = false; + Point2D point = null; + var newPoint = new Point2D() + { + X = x, + Z = z + }; + GeometryPoint gp = null; + if (type.HasValue) + { + // Get point of this type.. + gp = line.CharacteristicPoints.GetGeometryPoint(type.Value); + if (gp != null) + { + point = new Point2D(gp.X, gp.Z); + // Characteristic point annotation set, check location... + if (point.LocationEquals(newPoint)) + { + // Annotated point is at given location; We're done here! :) + return; + } + else + { + bool isAssignedToOtherCharacteristicPoints = + line.GetCharacteristicPoints(gp).Count(cpt => cpt != CharacteristicPointType.None) > 1; + if (isAssignedToOtherCharacteristicPoints) + { + // Other characteristic points exist with the same coordinates so add as new point + point = line.Geometry.GetPointAt(newPoint.X, newPoint.Z); // Get point at specified coords + if (point == null) + { + point = newPoint; + addPoint = true; + } + } + else + { + // Point is unique as characteristic point so set its coords to specified coords + point.X = x; + point.Z = z; + movedPointToMatch = true; + } + gp.X = point.X; + gp.Z = point.Z; + } + } + } + if (point == null) + { + point = line.Geometry.GetPointAt(x, z); // Get point at specified coords + } + if (point == null) + { + point = new Point2D() + { + X = x, + Z = z + }; + addPoint = true; + } + if (addPoint) + { + var newgp = new GeometryPoint(point.X, point.Z); + line.Geometry.Points.Add(newgp); + line.AddCharacteristicPoint(newgp, type ?? CharacteristicPointType.None); + } + else if (type.HasValue && !movedPointToMatch) + { + if (line.CharacteristicPoints.Any(cp => ReferenceEquals(cp.GeometryPoint, gp) && + cp.CharacteristicPointType != CharacteristicPointType.None)) + { + line.AddCharacteristicPoint(gp, type.Value); + } + else + { + int index = -1; + for (int i = 0; i < line.CharacteristicPoints.Count; i++) + { + if (ReferenceEquals(line.CharacteristicPoints[i].GeometryPoint, gp)) + { + index = i; + break; + } + } + line.CharacteristicPoints.Annotate(index, type.Value); + } + } + } + + /// + /// Removes the points between the two x values. The start and end points will + /// not be removed. + /// + /// Surfaceline being modified. + /// The non-inclusive starting X-coordinate. + /// The non-inclusive ending X-coordinate. + /// + public static void RemoveSegmentBetween(this SurfaceLine2 line, double startX, double endX) + { + RemoveGeometryPointsInRange(line, startX, endX, false); + } + + /// + /// Removes the points between the two x values. + /// + /// Surfaceline being modified. + /// The inclusive starting X-Coordinate. + /// The inclusive ending X-Coordinate. + /// + public static void RemoveSegmentIncluding(this SurfaceLine2 line, double startX, double endX) + { + RemoveGeometryPointsInRange(line, startX, endX, true); + } + + /// + /// Removes the points between the two x values. + /// + /// Surfaceline being modified. + /// The starting X-Coordinate. + /// The ending X-Coordinate. + /// Indicates if and + /// are inclusive bounds or not. + private static void RemoveGeometryPointsInRange(SurfaceLine2 line, double startX, double endX, bool isInclusiveRange) + { + foreach (var geometryPoint in GetGeometryPointsWithinRange(line, startX, endX, isInclusiveRange).ToArray()) + { + var characteristicPoints = line.CharacteristicPoints.Where(cp => ReferenceEquals(cp.GeometryPoint, geometryPoint)).ToArray(); + if (characteristicPoints.Length > 0) + { + // CharacteristicPointSet will manage both collections of CharacteristicPoint instances and Geometry + foreach (var characteristicPoint in characteristicPoints) + { + line.CharacteristicPoints.Remove(characteristicPoint); + } + } + else + { + // Notify change such that CharacteristicPointSet instances observing this + // geometry can update if required. + line.Geometry.Points.Remove(geometryPoint); + } + } + } + + /// + /// Retrieve all instances of a surfaceline that + /// fall with the range. + /// + /// Surfaceline being evaluated. + /// Starting X-coordinate. + /// Ending X-coordinate. + /// Indicates if and + /// are inclusive bounds or not. + /// Collection of characteristic points within the given range. + private static IEnumerable GetGeometryPointsWithinRange(SurfaceLine2 line, + double startX, double endX, bool isInclusiveRange) + { + if (isInclusiveRange) + { + return line.Geometry.Points.Where(cp => (cp.X >= startX || cp.X.AlmostEquals(startX, GeometryPoint.Precision)) && + (cp.X <= endX || cp.X.AlmostEquals(endX, GeometryPoint.Precision))); + } + return line.Geometry.Points.Where(cp => cp.X > startX && cp.X < endX); + } + + /// + /// Checks if a surfaceline has all characteristic point types required to describe + /// an inside shoulder. + /// + /// Surfaceline to be checked. + /// True if there are characteristic points defined that described the + /// inside shoulder; False otherwise. + public static bool HasShoulderInside(this SurfaceLine2 line) + { + return IsDefined(line, CharacteristicPointType.ShoulderTopInside) && + IsDefined(line, CharacteristicPointType.ShoulderBaseInside); + } + + /// + /// Checks if a surfaceline has all characteristic point types required to describe + /// a ditch. + /// + /// Surfaceline to be checked. + /// True if there are characteristic points defined that described the + /// ditch; False otherwise. + public static bool HasDitch(this SurfaceLine2 line) + { + return IsDefined(line, CharacteristicPointType.DitchDikeSide) && + IsDefined(line, CharacteristicPointType.DitchPolderSide); + } + + /// + /// Determines whether ditch is correct. + /// + /// true if ditch is correct, otherwise false + /// This methods checks if the following points have their X cooridnates + /// properly defined: + /// + /// + /// + /// + /// + /// + /// + public static bool IsDitchCorrect(this SurfaceLine2 line) + { + // No ditch then always ok + bool res = !line.HasDitch(); + if (!res) + { + // check the unchecked points + var bottomDitchDikeSide = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide); + var bottomDitchPolderSide = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide); + res = (bottomDitchDikeSide != null && bottomDitchPolderSide != null); + + // check the ditch points describe following shape: + // 0 0 + // \ / + // 0---0 + var ditchPolderSide = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + var ditchDikeSide = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + if (res) + { + res = ditchPolderSide.X >= bottomDitchPolderSide.X && + bottomDitchPolderSide.X >= bottomDitchDikeSide.X && + bottomDitchDikeSide.X >= ditchDikeSide.X && + bottomDitchDikeSide.Z <= ditchDikeSide.Z && + bottomDitchPolderSide.Z <= ditchPolderSide.Z; + } + } + return res; + } + + /// + /// Gets the starting point of the surface line. + /// + /// Starting point, or null if none of the considered points can be found. + /// + /// Method looks for the following characteristic points (in this order) and returns + /// the corresponding geometry point if present: + /// + /// + /// + /// + /// + /// + public static GeometryPoint GetStartingPoint(this SurfaceLine2 line) + { + return line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseOutside) ?? + line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopOutside) ?? + line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver); + } + + /// + /// Gets the default height of the dike table. + /// + /// null or height of table + public static double? GetDefaultDikeTableHeight(this SurfaceLine2 line) + { + // Consulted Erik Vastenburg about this: Use buitenkruinlijn as default DTH + GeometryPoint point = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver); + return point == null ? null : (double?)point.Z; + } + + /// + /// Make sure river level is above the bottom of the river. + /// + /// The evaluated surfaceline. + /// The current river level. + /// Bottom of the river if bottomlevel is above riverLevel, else + /// is required to have the characteristic point + /// when + /// is not null. + /// + public static double? EnsureWaterLevelIsAboveRiverBottom(this SurfaceLine2 line, double? riverLevel) + { + // Waterlevel is supposed to be at level of SurfaceLevelOutside when waterlevel + // is below SurfaceLevelOutside (is the bottom of the river) + if (riverLevel.HasValue) + { + double z = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside).Z; + riverLevel = Math.Max(z, riverLevel.Value); + } + return riverLevel; + } + + /// + /// Determines the intersection of a horizontal line with the surfaceline, starting + /// from to . + /// + /// The surfaceline being evaluated. + /// The height of the horizontal line. + /// The GeometryPoint at the intersection, or null if no intersection can + /// be found. + /// + /// Requires that the following characteristic points are defined: + /// + /// + /// + /// + /// + /// This method draws the horizontal line starting from the smallest X available + /// in the geometry to . + /// + /// When greater than + /// the height of the characteristic point . + /// + public static GeometryPoint DetermineIntersectionWithLevel(this SurfaceLine2 line, double level) + { + double startXCoordinate = line.Geometry.GetMinX(); + var waterlevelLine = GetWaterlevelLineStartingFrom(line, level, startXCoordinate); + + return DetermineIntersectionWithHorizontalLevel(line, waterlevelLine); + } + + /// + /// Create a horizontal line from a given starting X coordinate and ending at the + /// X coordinate of defined + /// in the surfaceline. + /// + /// The referenced surfaceline. + /// The height level of the horizontal line. + /// The starting coordinate. + /// The line segment. + private static Line GetWaterlevelLineStartingFrom(SurfaceLine2 line, double level, double startXCoordinate) + { + GeometryPoint pointEndOfprofile = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside); + var waterlevelLine = new Line(); + waterlevelLine.CreateHorizontalZLine(startXCoordinate, pointEndOfprofile.X, level); + + return waterlevelLine; + } + + /// + /// Finds the intersection point of a given horizontal line and the river side talud. + /// + /// The evaluated surfaceline. + /// The horizontal line. + /// The intersection point, or null in case no intersection was found. + /// When height of the horizontal line is + /// greater than the height of the characteristic point . + private static GeometryPoint DetermineIntersectionWithHorizontalLevel(SurfaceLine2 line, Line waterlevelLine) + { + ThrowWhenLevelAboveDike(line, waterlevelLine.BeginPoint.Z); + + var list = line.Geometry.Points.Where(point => + point.X >= line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside).X && + point.X <= line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X).ToList(); + + for (int i = 1; i < list.Count; i++) + { + var surfaceLineSegment = new Line(); + surfaceLineSegment.SetBeginAndEndPoints( + new Point2D(list[i - 1].X, list[i - 1].Z), + new Point2D(list[i].X, list[i].Z)); + + var intersectPoint = surfaceLineSegment.GetIntersectPointXz(waterlevelLine); + if (intersectPoint != null) + { + return new GeometryPoint(intersectPoint.X, intersectPoint.Z); + } + } + + return null; + } + + /// + /// Throw an in case the given height level is + /// higher than the characteristic point . + /// + private static void ThrowWhenLevelAboveDike(SurfaceLine2 line, double Level) + { + var dikeTopAtRiver = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver); + if (Level > dikeTopAtRiver.Z) + { + throw new SurfaceLineException(String.Format( + "Level ({0:F2} m) should NOT be higher than surface line ({1:F2}))", + Level, dikeTopAtRiver.Z)); + } + } } } \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/IContext.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/IContext.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/IContext.cs (revision 330) @@ -0,0 +1,108 @@ +// 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.Collections; + +namespace Deltares.DamEngine.Calculators.General +{ + /// + /// Application context class, which governs application wide overrides for visibility, + /// enabledness or domain data collections. + /// + public interface IContext + { + /// + /// Method indicating a visibility override value for a given instance object. + /// + /// Object being evaluated. + /// Name of the member which is part of . + /// True if visible; False if hidden; Null if no override. + bool? IsVisible(object source, string member); + + /// + /// Method indicating if the enabled override value for a given instance object. + /// + /// Object being evaluated. + /// Name of the member which is part of . + /// True if enabled; False if disabled; Null if no override. + bool? IsEnabled(object source, string member); + + /// + /// Method returning a collection of domain object for list or enum type members; + /// + /// Object being evaluated. + /// Name of the member which is part of . + /// A collection of domain object; Null if no override. + ICollection GetDomain(object source, string member); + + /// + /// Indicates to whether to perform the validation on the property or the method + /// + /// Object being evaluated. + /// Name of the member which is part of . + /// True or false if validation should be (or not be) performed; Null if no preference is given, but left over to the caller. + bool? ShouldValidate(object source, string member); + + /// + /// Gets the minimum value for a member. + /// + /// The source. + /// The member. + /// + double? GetMinimum(object source, string member); + + /// + /// Gets the maximum value for a member. + /// + /// The source. + /// The member. + /// + double? GetMaximum(object source, string member); + + /// + /// Gets the format string for a member. + /// + /// The type. + /// The source. + /// The member. + /// + string GetFormat(Type type, object source, string member); + + /// + /// Gets the default value for a memner. + /// + /// The type. + /// The member. + /// + object GetDefault(Type type, string member); + // waar is dit het handigst te implementeren (qua gebruik van)? + + /// + /// Gets the property order for UI display purposes. + /// + /// The type. + /// The member. + /// + int[] GetPropertyOrder(Type type, string member); + // is dit handig? Zo ja, dan ook een idee voor de andere attr? + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Location.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Location.cs (.../Location.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Location.cs (.../Location.cs) (revision 330) @@ -223,7 +223,6 @@ private bool redesignDikeShoulder = true; private double rwBankProtectionBottomLevel = 0; private double scenarioRiverLevel = 0; - private double? scenarioRiverLevelLow = null; private Segment segment; private SensorLocation sensorData; private double sheetPileLength = 0; @@ -2878,211 +2877,8 @@ }; } - #region IVisibleEnabled Members + - public bool IsEnabled(string property) - { - return true; - } - - public bool IsVisible(string property) - { - bool isPrimaryCalamity = (DamType == DamType.Primary && DamProjectType == DamProjectType.Calamity); - // bool isPrimaryDesign = (this.DamType == DamType.Primary && Location.DamProjectType == Data.DamProjectType.Design); - bool isRegionalCalamity = (DamType == DamType.Regional && DamProjectType == DamProjectType.Calamity); - bool isRegionalAssesment = (DamType == DamType.Regional && DamProjectType == DamProjectType.Assessment); - bool isRegionalDesign = (DamType == DamType.Regional && DamProjectType == DamProjectType.Design); - var arePlLineCreationExpertKnowledgeParametersNeeded = ArePlLineCreationExpertKnowledgeParametersNeeded(); - bool arePlLineCreationExpertKnowledgeParametersDrySituationNeeded = (PLLineCreationMethod == PLLineCreationMethod.ExpertKnowledgeRRD || - PLLineCreationMethod == PLLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD) && isRegionalAssesment; - var isDesign = IsDesign(); - bool isRegional = (DamType == DamType.Regional); - - // TODO: These string literals below should be replaced with the constants define in LocationParameterNames - switch (property) - { - case "DikeMaterialType": - return isRegional; - case "DetrimentFactor": - return isPrimaryCalamity || isRegionalCalamity || isRegionalDesign || isRegionalAssesment; - - case "BoezemLevelTp": - return isRegionalAssesment; // formerly known as MBP - case "BoezemLevelHbp": - return isRegionalAssesment; // formerly known as BP-GWS - case "BoezemLevelLbp": - return isRegionalAssesment; // formerly known as BP-GLW - - case "ShoulderEmbankmentMaterial": - return isDesign; - case "StabilityShoulderGrowSlope": - return isDesign; - case "StabilityShoulderGrowDeltaX": - return isDesign; - case "StabilitySlopeAdaptionDeltaX": - return isDesign; - case "UpliftCriterionStability": - return !isDesign; - case "UpliftCriterionPiping": - return !isDesign; - case "PlLineOffsetBelowDikeToeAtPolder": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "PlLineOffsetBelowDikeTopAtPolder": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "PlLineOffsetBelowDikeTopAtRiver": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "PlLineOffsetBelowShoulderBaseInside": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "PLLineOffsetDryBelowDikeToeAtPolder": - return arePlLineCreationExpertKnowledgeParametersDrySituationNeeded; - case "PLLineOffsetDryBelowDikeTopAtPolder": - return arePlLineCreationExpertKnowledgeParametersDrySituationNeeded; - case "PLLineOffsetDryBelowDikeTopAtRiver": - return arePlLineCreationExpertKnowledgeParametersDrySituationNeeded; - case "PLLineOffsetDryBelowShoulderBaseInside": - return arePlLineCreationExpertKnowledgeParametersDrySituationNeeded; - case "PlLineOffsetBelowDikeCrestMiddle": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "PlLineOffsetFactorBelowShoulderCrest": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "PlLineOffsetDryBelowDikeCrestMiddle": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "PlLineOffsetDryFactorBelowShoulderCrest": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "UsePlLineOffsetBelowDikeCrestMiddle": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "UsePlLineOffsetFactorBelowShoulderCrest": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "UsePlLineOffsetDryBelowDikeCrestMiddle": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "UsePlLineOffsetDryFactorBelowShoulderCrest": - return !isDesign && arePlLineCreationExpertKnowledgeParametersNeeded; - case "IntrusionVerticalWaterPressure": return true; - case "PolderLevelLow": - return isRegionalAssesment; - case "DredgingDepth": - return isRegionalAssesment; - case "SheetPileLength": - return isRegionalAssesment; - case "RwBankProtectionBottomLevel": - return isRegionalAssesment; - case "RedesignDikeHeight": - return isDesign; - case "DikeTableHeight": - return false; - case "RedesignDikeShoulder": - return isDesign; - case "StabilityDesignMethod": - return !isRegionalAssesment; - case "SlopeAdaptionStartCotangent": - return !isRegionalAssesment; - case "SlopeAdaptionEndCotangent": - return !isRegionalAssesment; - case "SlopeAdaptionStepCotangent": - return !isRegionalAssesment; - - // these will always be shown - case "Name": - return true; - case "XRd": - return true; - case "YRd": - return true; - case "DamType": - return true; - case "DikeRingId": - return true; - case "SegmentId": - return true; - case "Description": - return true; - case "TrafficLoad": - return true; - case "PolderLevel": - return true; - case "HeadPL2": - return true; - case "DampingFactorPL3": - return true; - case "DampingFactorPL4": - return true; - case "PenetrationLength": - return true; - case "SlopeDampingPiezometricHeightPolderSide": - return true; - case "PLLineCreationMethod": - return true; - case "MinimalCircleDepth": - return true; - case "StabilityZoneType": - return true; - case "DikeEmbankmentMaterial": - return true; - - // these will never be shown - case "RiverLevel": - return false; // Probably obsolete, because it is defined in the scenario - case "ScenarioRiverLevelLow": - return false; // Probably obsolete, because it is defined in the scenario - case "DistanceToEntryPoint": - return false; - case "LevelReductionInside": - return false; - case "LevelReductionOutside": - return false; - case "LayerHeightDistribution": - return false; - case "LayerHeightDeviation": - return false; - case "ModelFactorRequiredProbabilityOfFailurePiping": - return false; - case "RequiredProbabilityOfFailureStabilityInnerSlope": - return false; - case "RequiredProbabilityOfFailureStabilityOuterSlope": - return false; - case "ModelFactorRequiredSafetyFactorPiping": - return false; // Probably obsolete, because it is defined in the scenario - case "ModelFactorRequiredSafetyFactorStabilityInnerSlope": - return false; // Probably obsolete, because it is defined in the scenario - case "ModelFactorRequiredSafetyFactorStabilityOuterSlope": - return false; // Probably obsolete, because it is defined in the scenario - case "HasSensorData": - return false; - case "XRdDikeLine": - return false; - case "IsUseOriginalPLLineAssignments": - return false; - // The following design parameters are only visible for design option and when that design option does not involve the special Rijnland option. - case "NewDikeTopWidth": - case "UseNewDikeTopWidth": - case "NewDikeSlopeInside": - case "UseNewDikeSlopeInside": - case "NewDikeSlopeOutside": - case "UseNewDikeSlopeOutside": - case "NewShoulderTopSlope": - case "UseNewShoulderTopSlope": - case "NewShoulderBaseSlope": - case "UseNewShoulderBaseSlope": - case "NewMaxHeightShoulderAsFraction": - case "UseNewMaxHeightShoulderAsFraction": - case "NewMinDistanceDikeToeStartDitch": - case "UseNewMinDistanceDikeToeStartDitch": - case "UseNewDitchDefinition": - case "NewWidthDitchBottom": - case "NewDepthDitch": - case "NewSlopeAngleDitch": - return isDesign && StabilityDesignMethod != StabilityDesignMethod.SlopeAdaptionBeforeShoulderAdaption; - - // Next will only be shown if not Design as then they are part of the scenarios - case "HeadPl3": - return !isDesign; - case "HeadPl4": - return !isDesign; - default: - return true; - } - } - private bool IsDesign() { bool isDesign = (DamProjectType == DamProjectType.Design); @@ -3097,9 +2893,8 @@ PLLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD; return arePlLineCreationExpertKnowledgeParametersNeeded; } + - #endregion - public override string ToString() { return Name; Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenarioSelector.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenarioSelector.cs (.../Deltares.DamEngine.Data/RWScenarios/RWScenarioSelector.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenarioSelector.cs (.../Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenarioSelector.cs) (revision 330) @@ -23,8 +23,9 @@ using System.Collections.Generic; using System.Linq; using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.RWScenarios; -namespace Deltares.DamEngine.Data.RWScenarios +namespace Deltares.DamEngine.Calculators.Dikes_Assessment_Regional { public class RWScenarioSelector { Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Design/SurfaceLineAdapterException.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Design/SurfaceLineAdapterException.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Design/SurfaceLineAdapterException.cs (revision 330) @@ -0,0 +1,51 @@ +// 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; + +namespace Deltares.DamEngine.Calculators.General +{ + [Serializable] + public class SurfaceLineAdapterException : Exception + { + public SurfaceLineAdapterException() + { + } + + public SurfaceLineAdapterException(string message) + : base(message) + { + } + + public SurfaceLineAdapterException(string message, Exception inner) + : base(message, inner) + { + } + + protected SurfaceLineAdapterException( + SerializationInfo info, + StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file Fisheye: Tag 330 refers to a dead (removed) revision in file `dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenarioSelector.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/RequiredEntityNotExistException.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/RequiredEntityNotExistException.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/RequiredEntityNotExistException.cs (revision 330) @@ -0,0 +1,46 @@ +// 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; + +namespace Deltares.DamEngine.Calculators.General +{ + [Serializable] + public class RequiredEntityNotExistException : Exception + { + public RequiredEntityNotExistException(string messageFormat, Type type, object idValue) + : base(string.Format(messageFormat, type.Name, idValue), null) + { + } + + public RequiredEntityNotExistException(string messageFormat, Type type, object idValue, Exception inner) + : base(string.Format(messageFormat, type.Name, idValue), inner) + { + } + + protected RequiredEntityNotExistException( + SerializationInfo info, + StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/EvaluationJob.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/EvaluationJob.cs (.../EvaluationJob.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/EvaluationJob.cs (.../EvaluationJob.cs) (revision 330) @@ -22,6 +22,8 @@ using System.Collections.Generic; using System.Xml.Serialization; using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.General.Results; +using Deltares.DamEngine.Data.Standard.Calculation; namespace Deltares.DamEngine.Data.RWScenarios { @@ -58,30 +60,30 @@ } [XmlIgnore] - public string XML - { - get - { - XmlSerializer serializer = new XmlSerializer(); - return serializer.SerializeToString(this); - } - set - { - XmlDeserializer deserializer = new XmlDeserializer(); - EvaluationJob job = (EvaluationJob)deserializer.XmlDeserializeFromString(value, typeof(EvaluationJob)); +// public string XML +// { +// get +// { +// XmlSerializer serializer = new XmlSerializer(); +// return serializer.SerializeToString(this); +// } +// set +// { +// XmlDeserializer deserializer = new XmlDeserializer(); +// EvaluationJob job = (EvaluationJob)deserializer.XmlDeserializeFromString(value, typeof(EvaluationJob)); +// +// this.DikeName = job.DikeName; +// +// this.Locations.Clear(); +// this.Locations.AddRange(job.Locations); +// +// this.Results.Clear(); +// this.Results.AddRange(job.Results); +// this.schematizationFactorResults.Clear(); +// this.schematizationFactorResults.AddRange(job.schematizationFactorResults); +// } +// } - this.DikeName = job.DikeName; - - this.Locations.Clear(); - this.Locations.AddRange(job.Locations); - - this.Results.Clear(); - this.Results.AddRange(job.Results); - this.schematizationFactorResults.Clear(); - this.schematizationFactorResults.AddRange(job.schematizationFactorResults); - } - } - public List FailedEvaluatedLocations { get { return failedEvaluatedLocations; } Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityServiceFileParser.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityServiceFileParser.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityServiceFileParser.cs (revision 330) @@ -0,0 +1,438 @@ +// 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.Globalization; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using Deltares.DamEngine.Calculators.General; +using Deltares.DamEngine.Data.General.Results; +using Deltares.DamEngine.Data.Standard; + +namespace Deltares.DamEngine.Calculators.Stability +{ + /// + /// Parses the stability factor from the file contents of the stability output file + /// + /// + /// The parser looks for the [Dump] identifier and if found the [Data] id. + /// When found the next line contains several numbers. We need the first one which is the stability factor + /// + public class StabilityServiceFileParser + { + enum StabilityZone { stabilityZone1a = 1, stabilityZone1b = 2, stabilityZone2a = 3, stabilityZone2b = 4, stabilityZone3a = 5, stabilityZone3b = 6 }; + + /// + /// Gets the file content (text) from a file + /// + /// The name of the file + /// The content string + public static string GetFileContents(string fileName) + { + ThrowHelper.ThrowIfStringArgumentNullOrEmpty(fileName, StringResourceNames.OutputFileNameNotValid); + + ThrowHelper.ThrowIfFileNotExist(fileName, StringResourceNames.OutputFileNotExist); + + string fileContents; + using (var sr = new StreamReader(fileName)) + { + fileContents = sr.ReadToEnd(); + } + return fileContents; + } + + /// + /// Parses the content to get the safety factory + /// + /// The text to parse + /// The safety factor + private static double GetColumnValueNoZones(string fileContent, string columnName) + { + fileContent = ReadContentAfterIdentifier(fileContent, "[Dumps]"); + fileContent = ReadContentAfterIdentifier(fileContent, "[Dump]"); + fileContent = ReadContentAfterIdentifier(fileContent, "[Dump Header]"); + fileContent = ReadContentAfterIdentifier(fileContent, "[Column Indication]"); + + int columnIndex = GetDataColumnIndex(fileContent, columnName, "[End of Column Indication]"); + + fileContent = ReadContentAfterIdentifier(fileContent, "[Data]"); + + double columnValue = GetNumberFromLine(fileContent, columnIndex); + + return columnValue; + } + + private static bool IsUpliftResults(string fileContent) + { + fileContent = ReadContentAfterIdentifier(fileContent, "[MODEL]"); + if (fileContent.Contains(" 4 : Uplift Van")) + { + return true; + } + else + { + return false; + } + } + + private static MStabResultsSingleZone GetMStabResultsNoZones(string fileContent) + { + MStabResultsSingleZone mStabResultsStruct = new MStabResultsSingleZone(); + mStabResultsStruct.safetyFactor = GetColumnValueNoZones(fileContent, "Stability factor"); + if (IsUpliftResults(fileContent)) + mStabResultsStruct.safetyFactor = mStabResultsStruct.safetyFactor / 1.05; + mStabResultsStruct.circleSurfacePointLeftXCoordinate = GetColumnValueNoZones(fileContent, "X coordinate left surface"); + mStabResultsStruct.circleSurfacePointRightXCoordinate = GetColumnValueNoZones(fileContent, "X coordinate right surface"); + return mStabResultsStruct; + + } + + public static double GetBetaNoZones(string fileContent) + { + return GetColumnValueNoZones(fileContent, "Beta"); + } + + public static double GetBetaWithZones(string fileContent) + { + MStabResults mStabResults = new MStabResults(); + MStabResultsSingleZone? zoneResults1 = GetMStabResultsSingleZoneFrom(fileContent, StabilityZone.stabilityZone1a, StabilityZone.stabilityZone1b); + if (zoneResults1 != null) + { + mStabResults.zone1 = zoneResults1.Value; + } + else + { + throw new StabilityFileParseException("Stabilityzone 1a or 1b should exist"); + } + //mStabResults.zone2 = GetMStabResultsSingleZoneFrom(fileContent, StabilityZone.stabilityZone2a, StabilityZone.stabilityZone2b); + return mStabResults.zone1.beta; + } + + /// + /// Get the results from a zone (A or if not exists then B) + /// + /// + /// + private static MStabResultsSingleZone? GetMStabResultsSingleZoneFrom(string fileContent, StabilityZone zoneA, StabilityZone zoneB) + { + MStabResultsSingleZone? mStabResultsSingleZone = null; + MStabResultsSingleZone? zoneAResults = ParseZoneResults(fileContent, (int)zoneA); + MStabResultsSingleZone? zoneBResults = null; + if (zoneAResults != null) + { + mStabResultsSingleZone = zoneAResults.Value; + } + + else + { + zoneBResults = ParseZoneResults(fileContent, (int)zoneB); + if (zoneBResults != null) + { + mStabResultsSingleZone = zoneBResults.Value; + } + } + return mStabResultsSingleZone; + } + + /// + /// Read all relevant MStab results from file + /// + /// + /// + public static MStabResults GetMStabResults(string fileContent) + { + MStabResults mStabResults = new MStabResults(); + + ThrowHelper.ThrowIfStringArgumentNullOrEmpty(fileContent, StringResourceNames.OutputFileHasNoContent); + if (ParseHasZonePlotEnabled(fileContent)) + { + MStabResultsSingleZone? zoneResults1 = GetMStabResultsSingleZoneFrom(fileContent, StabilityZone.stabilityZone1a, StabilityZone.stabilityZone1b); + if (zoneResults1 != null) + { + mStabResults.zone1 = zoneResults1.Value; + } + else + { + throw new StabilityFileParseException("Stabilityzone 1a or 1b should exist"); + } + mStabResults.zone2 = GetMStabResultsSingleZoneFrom(fileContent, StabilityZone.stabilityZone2a, StabilityZone.stabilityZone2b); + } + else + { + MStabResultsSingleZone? noZoneResults = GetMStabResultsNoZones(fileContent); + mStabResults.zone1 = noZoneResults.Value; + } + return mStabResults; + } + + /// + /// Read all relevant SlopeW results from file + /// + /// + /// + public static MStabResults GetSlopeWResults(string fileContent) + { + MStabResults mStabResults = new MStabResults(); + + ThrowHelper.ThrowIfStringArgumentNullOrEmpty(fileContent, StringResourceNames.OutputFileHasNoContent); + fileContent = ReadContentAfterIdentifier(fileContent, "Bishop_Method_Fm="); + var indexEnd = fileContent.IndexOf("Applied_Lambda"); + fileContent = fileContent.Substring(17, indexEnd - 18); + fileContent.Trim(); + mStabResults.zone1.safetyFactor = Convert.ToDouble(fileContent); + + return mStabResults; + } + + public static double GetBeta(string fileContent) + { + ThrowHelper.ThrowIfStringArgumentNullOrEmpty(fileContent, StringResourceNames.OutputFileHasNoContent); + if (ParseHasZonePlotEnabled(fileContent)) + { + return GetBetaWithZones(fileContent); + } + else + { + return GetBetaNoZones(fileContent); + } + + } + + public static bool ParseHasZonePlotEnabled(string fileContent) + { + StringReader stringReader = new StringReader(fileContent); + string line = ""; + + while ((line = stringReader.ReadLine()) != null) + { + if (line.EndsWith(": Zone plot on")) + { + return int.Parse(line.Substring(0, 3)).Equals(1) ? true : false; + } + } + return false; + } + + private static bool ReadParameterColumnIndices(StringReader stringReader, ref int stabilityFactorIndex, + ref int xCoordinateLeftSurfaceIndex, ref int xCoordinateRightSurfaceIndex, ref int zoneNumberIndex, ref int betaIndex) + { + string line = ""; + const string startCondition = "[Column Indication]"; + const string endCondition = "[End of Column Indication]"; + const string headerSafetyFactor = "Stability factor"; + const string headerXCoordinateLeftSurface = "X coordinate left surface"; + const string headerXCoordinateRightSurface = "X coordinate right surface"; + const string headerZoneNumber = "Zone number"; + const string headerBeta = "Beta"; + + bool isEndCondition = false; + stabilityFactorIndex = -1; + xCoordinateLeftSurfaceIndex = -1; + xCoordinateRightSurfaceIndex = -1; + zoneNumberIndex = -1; + while ((line = stringReader.ReadLine()) != null) + { + if (line.Equals(startCondition)) + { + int columnIndex = 0; + while ((line = stringReader.ReadLine()) != null) + { + if (line.Equals(headerSafetyFactor)) + stabilityFactorIndex = columnIndex; + + if (line.Equals(headerXCoordinateLeftSurface)) + xCoordinateLeftSurfaceIndex = columnIndex; + + if (line.Equals(headerXCoordinateRightSurface)) + xCoordinateRightSurfaceIndex = columnIndex; + + if (line.Equals(headerZoneNumber)) + zoneNumberIndex = columnIndex; + + if (line.Equals(headerBeta)) + betaIndex = columnIndex; + + columnIndex++; + if (line.Equals(endCondition)) + { + isEndCondition = true; + break; + } + } + } + if (isEndCondition) + break; + } + + return ((stabilityFactorIndex >= 0) && (zoneNumberIndex >= 0) && (xCoordinateLeftSurfaceIndex >= 0) && (xCoordinateRightSurfaceIndex >= 0)) ? true : false; + } + + private static MStabResultsSingleZone? ParseZoneResults(string fileContent, int stabilityZone) + { + StringReader stringReader = new StringReader(fileContent); + string line = ""; + string zoneStabilityResults = null; + + int stabilityFactorIndex = -1; + int xCoordinateLeftSurfaceIndex = -1; + int xCoordinateRightSurfaceIndex = -1; + int zoneNumberIndex = -1; + int betaIndex = -1; + + MStabResultsSingleZone mStabResultsStruct = new MStabResultsSingleZone(); + while ((line = stringReader.ReadLine()) != null) + { + if (line.Equals("[Dump]")) + { + if (!ReadParameterColumnIndices(stringReader, ref stabilityFactorIndex, + ref xCoordinateLeftSurfaceIndex, ref xCoordinateRightSurfaceIndex, ref zoneNumberIndex, ref betaIndex)) + throw new StabilityFileParseException("Could not read Column Indication"); + + while ((line = stringReader.ReadLine()) != null) + { + if (line.Equals("[Data]")) + { + zoneStabilityResults = stringReader.ReadLine(); + + var zoneStabilityResultsElements = zoneStabilityResults.Split(' ').ToList().Where(x => x.Length > 0).ToArray(); + + if (zoneStabilityResultsElements != null) + { + if ((zoneStabilityResultsElements.Count() > stabilityFactorIndex) && (zoneStabilityResultsElements.Count() > zoneNumberIndex)) + { + try + { + if (int.Parse(zoneStabilityResultsElements[zoneNumberIndex]).Equals(stabilityZone)) + { + mStabResultsStruct.safetyFactor = zoneStabilityResultsElements[stabilityFactorIndex].ToType(); + if (IsUpliftResults(fileContent)) + mStabResultsStruct.safetyFactor = mStabResultsStruct.safetyFactor/1.05; + mStabResultsStruct.circleSurfacePointLeftXCoordinate = zoneStabilityResultsElements[xCoordinateLeftSurfaceIndex].ToType(); + mStabResultsStruct.circleSurfacePointRightXCoordinate = zoneStabilityResultsElements[xCoordinateRightSurfaceIndex].ToType(); + if (betaIndex > -1) + { + mStabResultsStruct.beta = zoneStabilityResultsElements[betaIndex].ToType(); + } + return mStabResultsStruct; + } + } + catch (Exception e) + { + throw new StabilityFileParseException("Could not parse Stabilityzone : " + e.ToString()); + } + } + else + throw new StabilityFileParseException("stabilityZone or stabilityFactorIndex not found"); + } + break; + } + } + } + } + return null; + } + + public static MStabResultsSingleZone? GetZoneStability1a(string fileContent) + { + return ParseZoneResults(fileContent, (int)StabilityZone.stabilityZone1a); + } + + public static MStabResultsSingleZone? GetZoneStability1b(string fileContent) + { + return ParseZoneResults(fileContent, (int)StabilityZone.stabilityZone1b); + } + + /// + /// + /// + /// + /// + /// + private static string ReadContentAfterIdentifier(string fileContent, string identifier) + { + if (!fileContent.Contains(identifier)) + throw new StabilityFileParseException("Stability file doesn't contain identifier " + identifier); + fileContent = fileContent.Substring(fileContent.IndexOf(identifier)); + return fileContent.Replace(identifier + Environment.NewLine, ""); + } + + /// + /// + /// + /// + /// Returns -1 if identifier is not found + /// + /// The content to search in + /// The identifier to look for + /// The index of the column + private static int GetDataColumnIndex(string fileContent, string identifier, string endTag) + { + if (!fileContent.Contains(identifier)) + throw new StabilityFileParseException(); + + var items = fileContent + .Substring(0, fileContent.IndexOf(endTag) - Environment.NewLine.Length) + .Replace(Environment.NewLine, ";") + .Split(';'); + + var foundMatch = false; + var i = -1; + if (items.Length == 1 && StringsAreEqual(items[0], identifier)) + i = 0; + else if (items.Length > 1) + { + foreach (var word in items) + { + ++i; + if (StringsAreEqual(word, identifier)) + { + foundMatch = true; + break; + } + } + } + + if (i == -1 || !foundMatch) + throw new StabilityFileParseException(); + + return i; + } + + private static bool StringsAreEqual(string left, string right) + { + return ((!string.IsNullOrEmpty(left) || left.Trim() == "") && + left.Equals(right, StringComparison.InvariantCulture)); + } + + /// + /// + /// + /// + /// + private static double GetNumberFromLine(string fileContent, int idPos) + { + var doublesPattern = new Regex(@"-?\d+(?:\.\d+)?"); + var matches = doublesPattern.Matches(fileContent); + return double.Parse(matches[idPos].Value, NumberStyles.Any, CultureInfo.InvariantCulture); + } + } +} Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityCalculationException.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityCalculationException.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityCalculationException.cs (revision 330) @@ -0,0 +1,43 @@ +// 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; + +namespace Deltares.DamEngine.Calculators.Stability +{ + [Serializable] + public class StabilityCalculationException : Exception + { + public StabilityCalculationException() {} + + public StabilityCalculationException(string message) + : base(message) {} + + public StabilityCalculationException(string message, Exception inner) + : base(message, inner) {} + + protected StabilityCalculationException( + SerializationInfo info, + StreamingContext context) + : base(info, context) {} + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs (.../DAMFailureMechanismeCalculator.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs (.../DAMFailureMechanismeCalculator.cs) (revision 330) @@ -28,11 +28,18 @@ using System.Text.RegularExpressions; using System.Xml.Linq; using System.Xml.Serialization; +using Deltares.DamEngine.Calculators.General; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.NWO; +using Deltares.DamEngine.Data.General.Results; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.Data.Probabilistic; +using Deltares.DamEngine.Data.Standard.Calculation; +using Deltares.DamEngine.Data.Standard.Language; +using Deltares.DamEngine.Data.Standard.Logging; +using Deltares.DamEngine.Data.Standard.Validation; namespace Deltares.DamEngine.Calculators { @@ -161,7 +168,6 @@ var validationError = adaptedSurfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); if (validationError != null) { - adaptedSurfaceLine.Dispose(); throw new SurfaceLineException(validationError.Text); } @@ -193,19 +199,19 @@ private void CalculateForScenario(Scenario scenario) { - switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType) - { - case FailureMechanismSystemType.StabilityInside: - case FailureMechanismSystemType.StabilityOutside: - CalculateStabilityForScenario(scenario, 0); - break; - case FailureMechanismSystemType.Piping: - CalculatePipingForScenario(scenario); - break; - case FailureMechanismSystemType.FlowSlide: - CalculateFlowSlideForScenario(scenario); - break; - } +// switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType) +// { +// case FailureMechanismSystemType.StabilityInside: +// case FailureMechanismSystemType.StabilityOutside: +// CalculateStabilityForScenario(scenario, 0); +// break; +// case FailureMechanismSystemType.Piping: +// CalculatePipingForScenario(scenario); +// break; +// case FailureMechanismSystemType.FlowSlide: +// CalculateFlowSlideForScenario(scenario); +// break; +// } } /// @@ -218,124 +224,124 @@ /// The piping calculator. /// The soil profile probability. /// - private bool CheckAndAdaptBetasWaterLevelsWhenNeeded(double[] betas, double[] waterLevels, Scenario scenario, SurfaceLine2 newSurfaceLine, PipingCalculator pipingCalculator, SoilGeometryProbability soilProfileProbability) - { - int nrValidItems = 0; - for (int i = 0; i < 3; i++) - { - // If beta >= 10, then in fact no uplift occured and probability of failure is in fact 0. Such a value would be invalid for the design point calculation. - if (betas[i] < 10) - { - nrValidItems++; - } - } - if ((nrValidItems == 0) || (nrValidItems == 3)) - { - return (nrValidItems == 3); - } - else - { - if (nrValidItems == 1) - { - // extra calculation(s) needed to determine a second valid beta (<10) to be able to perform a design point calculation. Search between toplevel - // (beta[0]) and middle level a waterlevel at which a beta is valid and use that one (adapt the levels too of course). - double? betaloc = null; - bool lReady = false; - double locLevel = (waterLevels[0] + waterLevels[1])*0.5; - var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); - waterLevelProbabilistic.Distribution = (int) DistributionType.LogNormal; - waterLevelProbabilistic.StandardDeviation = 0.01; - waterLevelProbabilistic.IsUsed = false; - while (!lReady) - { - waterLevelProbabilistic.Mean = locLevel; - betaloc = CalculatePipingReliabilityIndexForSurface(scenario, newSurfaceLine, pipingCalculator, soilProfileProbability, - waterLevelProbabilistic); - lReady = betaloc.Value < 10; - if (lReady) - { - betas[1] = betaloc.Value; - waterLevels[1] = locLevel; - } - else - { - locLevel = locLevel + (waterLevels[0] + locLevel)*0.5; - lReady = Math.Abs(locLevel - waterLevels[0]) < 0.0001; - } - } +// private bool CheckAndAdaptBetasWaterLevelsWhenNeeded(double[] betas, double[] waterLevels, Scenario scenario, SurfaceLine2 newSurfaceLine, PipingCalculator pipingCalculator, SoilGeometryProbability soilProfileProbability) +// { +// int nrValidItems = 0; +// for (int i = 0; i < 3; i++) +// { +// // If beta >= 10, then in fact no uplift occured and probability of failure is in fact 0. Such a value would be invalid for the design point calculation. +// if (betas[i] < 10) +// { +// nrValidItems++; +// } +// } +// if ((nrValidItems == 0) || (nrValidItems == 3)) +// { +// return (nrValidItems == 3); +// } +// else +// { +// if (nrValidItems == 1) +// { +// // extra calculation(s) needed to determine a second valid beta (<10) to be able to perform a design point calculation. Search between toplevel +// // (beta[0]) and middle level a waterlevel at which a beta is valid and use that one (adapt the levels too of course). +// double? betaloc = null; +// bool lReady = false; +// double locLevel = (waterLevels[0] + waterLevels[1])*0.5; +// var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); +// waterLevelProbabilistic.Distribution = (int) DistributionType.LogNormal; +// waterLevelProbabilistic.StandardDeviation = 0.01; +// waterLevelProbabilistic.IsUsed = false; +// while (!lReady) +// { +// waterLevelProbabilistic.Mean = locLevel; +// betaloc = CalculatePipingReliabilityIndexForSurface(scenario, newSurfaceLine, pipingCalculator, soilProfileProbability, +// waterLevelProbabilistic); +// lReady = betaloc.Value < 10; +// if (lReady) +// { +// betas[1] = betaloc.Value; +// waterLevels[1] = locLevel; +// } +// else +// { +// locLevel = locLevel + (waterLevels[0] + locLevel)*0.5; +// lReady = Math.Abs(locLevel - waterLevels[0]) < 0.0001; +// } +// } +// +// // now set nrValidItems to 2 to get the required third valid beta by axtrapolation +// nrValidItems = 2; +// } +// if (nrValidItems == 2) +// { +// // use the 2 valid betas to extrapolate a valid third beta value. +// betas[2] = Routines2D.LinInpolY(waterLevels[0], betas[0], waterLevels[1], betas[1], waterLevels[2]); +// } +// return true; +// } +// } - // now set nrValidItems to 2 to get the required third valid beta by axtrapolation - nrValidItems = 2; - } - if (nrValidItems == 2) - { - // use the 2 valid betas to extrapolate a valid third beta value. - betas[2] = Routines2D.LinInpolY(waterLevels[0], betas[0], waterLevels[1], betas[1], waterLevels[2]); - } - return true; - } - } +// private double? CalculatePipingFailureProbabilityAdvanced(PipingCalculator pipingCalculator, Scenario scenario, +// SoilGeometryProbability soilProfileProbability, SurfaceLine2 newSurfaceLine) +// { +// double[] waterLevels = scenario.DetermineProperWaterlevelsForProbabilisticAdvanced(); +// var betas = new double[3]; +// var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); +// for (int i = 0; i < 3; i++) +// { +// betas[i] = 1; +// waterLevelProbabilistic.Mean = waterLevels[i]; +// string calculationName = String.Format("Prob{0}_Loc({1})_Sce({2})_Pro({3})_wl({4})", +// PipingModelType.Sellmeijer.ToString(), scenario.Location.Name, scenario.LocationScenarioID, soilProfileProbability.SoilGeometryName, i); +// calculationName = Regex.Replace(calculationName, @"[\\\/:\*\?""'<>|.]", "_"); +// pipingCalculator.FilenameCalculation = pipingCalculator.PipingCalculationDirectory + calculationName; +// +// double? betaloc = CalculatePipingReliabilityIndexForSurface(scenario, newSurfaceLine, pipingCalculator, soilProfileProbability, waterLevelProbabilistic); +// if (betaloc != null) +// { +// betas[i] = betaloc.Value; +// } +// } - private double? CalculatePipingFailureProbabilityAdvanced(PipingCalculator pipingCalculator, Scenario scenario, - SoilGeometryProbability soilProfileProbability, SurfaceLine2 newSurfaceLine) - { - double[] waterLevels = scenario.DetermineProperWaterlevelsForProbabilisticAdvanced(); - var betas = new double[3]; - var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); - for (int i = 0; i < 3; i++) - { - betas[i] = 1; - waterLevelProbabilistic.Mean = waterLevels[i]; - string calculationName = String.Format("Prob{0}_Loc({1})_Sce({2})_Pro({3})_wl({4})", - PipingModelType.Sellmeijer.ToString(), scenario.Location.Name, scenario.LocationScenarioID, soilProfileProbability.SoilGeometryName, i); - calculationName = Regex.Replace(calculationName, @"[\\\/:\*\?""'<>|.]", "_"); - pipingCalculator.FilenameCalculation = pipingCalculator.PipingCalculationDirectory + calculationName; - - double? betaloc = CalculatePipingReliabilityIndexForSurface(scenario, newSurfaceLine, pipingCalculator, soilProfileProbability, waterLevelProbabilistic); - if (betaloc != null) - { - betas[i] = betaloc.Value; - } - } - // Note Bka: For now, set MHW to original max water level (= river level + WaterHeightDecimeringsHoogte) and set // Decimate to the original WaterHeightDecimeringsHoogte. Han Best has to approve this! // After consulting Best, the next decision is made. MHW should be the riverlevel. And if the maxwaterlevel is smaller than MHW,then a designpoint // calculation is not longer required as the safety is determined by the maxwaterlevel. So just return the Beta[0] (= beta at maxwaterlevel) in // that case. - if (scenario.RiverLevel > scenario.MaxWaterLevel) - { - return Probabilistic.Probabilistic.NormalDistribution(-betas[0]); - } - else - { - if (CheckAndAdaptBetasWaterLevelsWhenNeeded(betas, waterLevels, scenario, newSurfaceLine, pipingCalculator, soilProfileProbability)) - { - var designPointWater = new DesignPointCalculation(); - designPointWater.Betas = betas; - designPointWater.Waterlevels = waterLevels; - designPointWater.MHW = (double) (scenario.RiverLevel); - designPointWater.Decimate = (double) scenario.WaterHeightDecimeringsHoogte; - designPointWater.Exceed = DesignPointCalculation.ExceedingSet.twoThousend; - designPointWater.IsMaxLevelUsed = false; - designPointWater.MaxLevel = 0; - if (designPointWater.CalculateTheWaterDesignpoint()) - { - return Probabilistic.Probabilistic.NormalDistribution(-designPointWater.Beta); - } - else - { - // result could not be determined. - throw new DamFailureMechanismeCalculatorException("Water design point calculation failed"); - } - } - else - { - // total situation is safe, so return 0. - return 0; - } - } - } +// if (scenario.RiverLevel > scenario.MaxWaterLevel) +// { +// return Probabilistic.Probabilistic.NormalDistribution(-betas[0]); +// } +// else +// { +// if (CheckAndAdaptBetasWaterLevelsWhenNeeded(betas, waterLevels, scenario, newSurfaceLine, pipingCalculator, soilProfileProbability)) +// { +// var designPointWater = new DesignPointCalculation(); +// designPointWater.Betas = betas; +// designPointWater.Waterlevels = waterLevels; +// designPointWater.MHW = (double) (scenario.RiverLevel); +// designPointWater.Decimate = (double) scenario.WaterHeightDecimeringsHoogte; +// designPointWater.Exceed = DesignPointCalculation.ExceedingSet.twoThousend; +// designPointWater.IsMaxLevelUsed = false; +// designPointWater.MaxLevel = 0; +// if (designPointWater.CalculateTheWaterDesignpoint()) +// { +// return Probabilistic.Probabilistic.NormalDistribution(-designPointWater.Beta); +// } +// else +// { +// // result could not be determined. +// throw new DamFailureMechanismeCalculatorException("Water design point calculation failed"); +// } +// } +// else +// { +// // total situation is safe, so return 0. +// return 0; +// } +// } +// } /// /// @@ -346,281 +352,281 @@ /// /// /// - private double? CalculatePipingReliabilityIndexForSurface(Scenario scenario, SurfaceLine2 newSurfaceLine, PipingCalculator pipingCalculator, SoilGeometryProbability soilProfileProbability, - ProbabilisticStruct waterLevel) - { - double? betaloc; - if (newSurfaceLine != null) - { - betaloc = pipingCalculator.CalculateReliabilityIndex(scenario.Location, newSurfaceLine, soilProfileProbability.SoilProfile, waterLevel); - } - else - { - betaloc = pipingCalculator.CalculateReliabilityIndex(scenario.Location, scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName), soilProfileProbability.SoilProfile, waterLevel); - } - return betaloc; - } +// private double? CalculatePipingReliabilityIndexForSurface(Scenario scenario, SurfaceLine2 newSurfaceLine, PipingCalculator pipingCalculator, SoilGeometryProbability soilProfileProbability, +// ProbabilisticStruct waterLevel) +// { +// double? betaloc; +// if (newSurfaceLine != null) +// { +// betaloc = pipingCalculator.CalculateReliabilityIndex(scenario.Location, newSurfaceLine, soilProfileProbability.SoilProfile, waterLevel); +// } +// else +// { +// betaloc = pipingCalculator.CalculateReliabilityIndex(scenario.Location, scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName), soilProfileProbability.SoilProfile, waterLevel); +// } +// return betaloc; +// } /// /// /// /// /// /// - private void CalculatePipingForScenario(Scenario scenario) - { - var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); - string pipingCalculationDirectory = GetPipingCalculationBaseDirectory(); - try - { - var validSoilProfileProbabilities = SelectPipingProbabilities(scenario.Location.Segment.SoilProfileProbabilities); - if (validSoilProfileProbabilities.Count == 0) - { - throw new DamFailureMechanismeCalculatorException(String.Format("No piping profiles to calcutate for location {0}", scenario.Location.Name)); - } - foreach (var soilProfileProbability in validSoilProfileProbabilities) - { - try - { - var pipingResults = new PipingResults(); - foreach (PipingModelType pipingCalculationType in Enum.GetValues(typeof(PipingModelType))) - { - var pipingProbabilisticParameters = new PipingProbabilisticParameters(scenario.Location.LayerHeightDistribution, scenario.Location.LayerHeightDeviation); - PipingCalculator pipingCalculator = pipingCalculatorFactory(scenario.Location, scenario.Location.CreateModelParametersForPLLines(), - pipingCalculationType, - scenario.GetUpliftCriterionPiping(scenario.Location.ModelFactors.UpliftCriterionPiping), - scenario.GetRequiredSafetyFactorPiping(scenario.Location.ModelFactors.RequiredSafetyFactorPiping), - pipingProbabilisticParameters); - pipingCalculator.PipingCalculationDirectory = pipingCalculationDirectory; - double? safetyFactor = null; - double? failureProbability = null; - double? failureProbabilityAdvanced = null; - double? pipingExitPointX = null; - double? upliftFactor = null; - double? heaveFactor = null; - try - { - switch (ProbabilisticType) - { - case ProbabilisticType.Deterministic: - safetyFactor = pipingCalculator.CalculatePipingFactor( - scenario.Location, - scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName), - soilProfileProbability.SoilProfile, - scenario.RiverLevel); - if (pipingCalculator.UpliftLocationAndResult != null) - { - pipingExitPointX = pipingCalculator.UpliftLocationAndResult.X; - upliftFactor = pipingCalculator.UpliftLocationAndResult.UpliftFactor; - heaveFactor = pipingCalculator.HeaveFactor; - } - break; - case ProbabilisticType.Probabilistic: - waterLevelProbabilistic.Mean = scenario.RiverLevel; +// private void CalculatePipingForScenario(Scenario scenario) +// { +// var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); +// string pipingCalculationDirectory = GetPipingCalculationBaseDirectory(); +// try +// { +// var validSoilProfileProbabilities = SelectPipingProbabilities(scenario.Location.Segment.SoilProfileProbabilities); +// if (validSoilProfileProbabilities.Count == 0) +// { +// throw new DamFailureMechanismeCalculatorException(String.Format("No piping profiles to calcutate for location {0}", scenario.Location.Name)); +// } +// foreach (var soilProfileProbability in validSoilProfileProbabilities) +// { +// try +// { +// var pipingResults = new PipingResults(); +// foreach (PipingModelType pipingCalculationType in Enum.GetValues(typeof(PipingModelType))) +// { +// var pipingProbabilisticParameters = new PipingProbabilisticParameters(scenario.Location.LayerHeightDistribution, scenario.Location.LayerHeightDeviation); +// PipingCalculator pipingCalculator = pipingCalculatorFactory(scenario.Location, scenario.Location.CreateModelParametersForPLLines(), +// pipingCalculationType, +// scenario.GetUpliftCriterionPiping(scenario.Location.ModelFactors.UpliftCriterionPiping), +// scenario.GetRequiredSafetyFactorPiping(scenario.Location.ModelFactors.RequiredSafetyFactorPiping), +// pipingProbabilisticParameters); +// pipingCalculator.PipingCalculationDirectory = pipingCalculationDirectory; +// double? safetyFactor = null; +// double? failureProbability = null; +// double? failureProbabilityAdvanced = null; +// double? pipingExitPointX = null; +// double? upliftFactor = null; +// double? heaveFactor = null; +// try +// { +// switch (ProbabilisticType) +// { +// case ProbabilisticType.Deterministic: +// safetyFactor = pipingCalculator.CalculatePipingFactor( +// scenario.Location, +// scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName), +// soilProfileProbability.SoilProfile, +// scenario.RiverLevel); +// if (pipingCalculator.UpliftLocationAndResult != null) +// { +// pipingExitPointX = pipingCalculator.UpliftLocationAndResult.X; +// upliftFactor = pipingCalculator.UpliftLocationAndResult.UpliftFactor; +// heaveFactor = pipingCalculator.HeaveFactor; +// } +// break; +// case ProbabilisticType.Probabilistic: +// waterLevelProbabilistic.Mean = scenario.RiverLevel; +// +// string calculationName = String.Format("Prob{0}_Loc({1})_Sce({2})_Pro({3})", +// pipingCalculationType.ToString(), scenario.Location.Name, scenario.LocationScenarioID, soilProfileProbability.SoilGeometryName); +// calculationName = Regex.Replace(calculationName, @"[\\\/:\*\?""'<>|.]", "_"); +// pipingCalculator.FilenameCalculation = pipingCalculator.PipingCalculationDirectory + calculationName; +// +// failureProbability = +// pipingCalculator.CalculatePipingFailureProbability( +// scenario.Location, +// scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName), +// soilProfileProbability.SoilProfile, +// waterLevelProbabilistic); +// break; +// case ProbabilisticType.ProbabilisticFragility: +// failureProbabilityAdvanced = CalculatePipingFailureProbabilityAdvanced(pipingCalculator, scenario, soilProfileProbability, null); +// break; +// } +// } +// catch (Exception exception) +// { +// throw new DamFailureMechanismeCalculatorException(exception.Message); +// } +// +// if (pipingCalculationType == PipingModelType.Sellmeijer) +// { +// scenario.SetSafetyFactorPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, safetyFactor); +// if (ProbabilisticType == ProbabilisticType.ProbabilisticFragility) +// { +// scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, +// failureProbabilityAdvanced); +// } +// else +// { +// scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, +// failureProbability); +// } +// } +// pipingResults.CalculationName = pipingCalculator.FilenameCalculation; +// pipingResults.CalculationSubDir = @"PipingCalculation\\"; +// pipingResults.PipingExitPointX = pipingExitPointX; +// pipingResults.UpliftFactor = upliftFactor; +// pipingResults.HeaveFactor = heaveFactor; +// switch (pipingCalculationType) +// { +// case PipingModelType.Bligh: +// pipingResults.BlighHCritical = pipingCalculator.HCritical; +// pipingResults.BlighPipingFactor = safetyFactor; +// break; +// case PipingModelType.Sellmeijer: +// pipingResults.SellmeijerHCritical = pipingCalculator.HCritical; +// pipingResults.SellmeijerPipingFactor = safetyFactor; +// break; +// case PipingModelType.Sellmeijer2Forces: +// pipingResults.Sellmeijer2ForcesHCritical = pipingCalculator.HCritical; +// pipingResults.Sellmeijer2ForcesPipingFactor = safetyFactor; +// break; +// case PipingModelType.Sellmeijer4Forces: +// pipingResults.Sellmeijer4ForcesHCritical = pipingCalculator.HCritical; +// pipingResults.Sellmeijer4ForcesPipingFactor = safetyFactor; +// break; +// case PipingModelType.Wti2017: +// pipingResults.Wti2017HCritical = pipingCalculator.HCritical; +// pipingResults.Wti2017PipingFactor = safetyFactor; +// break; +// } +// } +// scenario.SetPipingResults(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, pipingResults); +// } +// catch (DamFailureMechanismeCalculatorException calculatorException) +// { +// string errorMessage = "FAIL: " + calculatorException.Message; +// Exception innerException = calculatorException.InnerException; +// while (innerException != null) +// { +// errorMessage = errorMessage + ";" + innerException.Message; +// innerException = innerException.InnerException; +// } +// scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, errorMessage); +// +// calculatorException.Scenario = scenario; +// throw calculatorException; +// } +// } +// } +// catch (Exception exception) +// { +// scenario.Errors.Add(exception.Message); +// Exception innerException = exception.InnerException; +// while (innerException != null) +// { +// scenario.Errors.Add(innerException.Message); +// innerException = innerException.InnerException; +// } +// } +// } - string calculationName = String.Format("Prob{0}_Loc({1})_Sce({2})_Pro({3})", - pipingCalculationType.ToString(), scenario.Location.Name, scenario.LocationScenarioID, soilProfileProbability.SoilGeometryName); - calculationName = Regex.Replace(calculationName, @"[\\\/:\*\?""'<>|.]", "_"); - pipingCalculator.FilenameCalculation = pipingCalculator.PipingCalculationDirectory + calculationName; - - failureProbability = - pipingCalculator.CalculatePipingFailureProbability( - scenario.Location, - scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName), - soilProfileProbability.SoilProfile, - waterLevelProbabilistic); - break; - case ProbabilisticType.ProbabilisticFragility: - failureProbabilityAdvanced = CalculatePipingFailureProbabilityAdvanced(pipingCalculator, scenario, soilProfileProbability, null); - break; - } - } - catch (Exception exception) - { - throw new DamFailureMechanismeCalculatorException(exception.Message); - } - - if (pipingCalculationType == PipingModelType.Sellmeijer) - { - scenario.SetSafetyFactorPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, safetyFactor); - if (ProbabilisticType == ProbabilisticType.ProbabilisticFragility) - { - scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, - failureProbabilityAdvanced); - } - else - { - scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, - failureProbability); - } - } - pipingResults.CalculationName = pipingCalculator.FilenameCalculation; - pipingResults.CalculationSubDir = @"PipingCalculation\\"; - pipingResults.PipingExitPointX = pipingExitPointX; - pipingResults.UpliftFactor = upliftFactor; - pipingResults.HeaveFactor = heaveFactor; - switch (pipingCalculationType) - { - case PipingModelType.Bligh: - pipingResults.BlighHCritical = pipingCalculator.HCritical; - pipingResults.BlighPipingFactor = safetyFactor; - break; - case PipingModelType.Sellmeijer: - pipingResults.SellmeijerHCritical = pipingCalculator.HCritical; - pipingResults.SellmeijerPipingFactor = safetyFactor; - break; - case PipingModelType.Sellmeijer2Forces: - pipingResults.Sellmeijer2ForcesHCritical = pipingCalculator.HCritical; - pipingResults.Sellmeijer2ForcesPipingFactor = safetyFactor; - break; - case PipingModelType.Sellmeijer4Forces: - pipingResults.Sellmeijer4ForcesHCritical = pipingCalculator.HCritical; - pipingResults.Sellmeijer4ForcesPipingFactor = safetyFactor; - break; - case PipingModelType.Wti2017: - pipingResults.Wti2017HCritical = pipingCalculator.HCritical; - pipingResults.Wti2017PipingFactor = safetyFactor; - break; - } - } - scenario.SetPipingResults(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, pipingResults); - } - catch (DamFailureMechanismeCalculatorException calculatorException) - { - string errorMessage = "FAIL: " + calculatorException.Message; - Exception innerException = calculatorException.InnerException; - while (innerException != null) - { - errorMessage = errorMessage + ";" + innerException.Message; - innerException = innerException.InnerException; - } - scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, errorMessage); - - calculatorException.Scenario = scenario; - throw calculatorException; - } - } - } - catch (Exception exception) - { - scenario.Errors.Add(exception.Message); - Exception innerException = exception.InnerException; - while (innerException != null) - { - scenario.Errors.Add(innerException.Message); - innerException = innerException.InnerException; - } - } - } - /// /// Calculates failuremechanism flowslide for scenario. /// /// The scenario. - private void CalculateFlowSlideForScenario(Scenario scenario) - { - try - { - var validSoilProfileProbabilities = SelectFlowSlideProbabilities(scenario.Location.Segment.SoilProfileProbabilities); - if (validSoilProfileProbabilities.Count == 0) - { - throw new DamFailureMechanismeCalculatorException(String.Format("No profiles to calcutate for location {0}", scenario.Location.Name)); - } - foreach (var soilProfileProbability in validSoilProfileProbabilities) - { - try - { - if (soilProfileProbability.SoilProfile == null) - { - throw new DamFailureMechanismeCalculatorException(String.Format("Soilprofile is not 1D for location {0}", - scenario.Location.Name)); - } - var flowSlideCalculations = new FlowSlideCalculations(); - using (var flowSlideProject = CreateFlowSlideProject(scenario, soilProfileProbability)) - { - string calculationName = StabilityCalculator.DetermineCalculationFilename(scenario.Location.Name, scenario.LocationScenarioID, - soilProfileProbability.SoilGeometryName, 0); - WriteFlowSlideProjectToFile(flowSlideProject, calculationName); +// private void CalculateFlowSlideForScenario(Scenario scenario) +// { +// try +// { +// var validSoilProfileProbabilities = SelectFlowSlideProbabilities(scenario.Location.Segment.SoilProfileProbabilities); +// if (validSoilProfileProbabilities.Count == 0) +// { +// throw new DamFailureMechanismeCalculatorException(String.Format("No profiles to calcutate for location {0}", scenario.Location.Name)); +// } +// foreach (var soilProfileProbability in validSoilProfileProbabilities) +// { +// try +// { +// if (soilProfileProbability.SoilProfile == null) +// { +// throw new DamFailureMechanismeCalculatorException(String.Format("Soilprofile is not 1D for location {0}", +// scenario.Location.Name)); +// } +// var flowSlideCalculations = new FlowSlideCalculations(); +// using (var flowSlideProject = CreateFlowSlideProject(scenario, soilProfileProbability)) +// { +// string calculationName = StabilityCalculator.DetermineCalculationFilename(scenario.Location.Name, scenario.LocationScenarioID, +// soilProfileProbability.SoilGeometryName, 0); +// WriteFlowSlideProjectToFile(flowSlideProject, calculationName); +// +// flowSlideCalculations.RunCalculation(flowSlideProject); +// double safetyFactor = flowSlideProject.ResultOverallFactor; +// scenario.SetSafetyFactorFlowSlide(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, safetyFactor); +// } +// } +// catch (DamFailureMechanismeCalculatorException calculatorException) +// { +// string errorMessage = "FAIL: " + calculatorException.Message; +// Exception innerException = calculatorException.InnerException; +// while (innerException != null) +// { +// errorMessage = errorMessage + ";" + innerException.Message; +// innerException = innerException.InnerException; +// } +// scenario.SetResultMessage(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName, errorMessage); +// +// calculatorException.Scenario = scenario; +// throw calculatorException; +// } +// } +// } +// catch (Exception exception) +// { +// scenario.Errors.Add(exception.Message); +// Exception innerException = exception.InnerException; +// while (innerException != null) +// { +// scenario.Errors.Add(innerException.Message); +// innerException = innerException.InnerException; +// } +// } +// } - flowSlideCalculations.RunCalculation(flowSlideProject); - double safetyFactor = flowSlideProject.ResultOverallFactor; - scenario.SetSafetyFactorFlowSlide(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, safetyFactor); - } - } - catch (DamFailureMechanismeCalculatorException calculatorException) - { - string errorMessage = "FAIL: " + calculatorException.Message; - Exception innerException = calculatorException.InnerException; - while (innerException != null) - { - errorMessage = errorMessage + ";" + innerException.Message; - innerException = innerException.InnerException; - } - scenario.SetResultMessage(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName, errorMessage); - - calculatorException.Scenario = scenario; - throw calculatorException; - } - } - } - catch (Exception exception) - { - scenario.Errors.Add(exception.Message); - Exception innerException = exception.InnerException; - while (innerException != null) - { - scenario.Errors.Add(innerException.Message); - innerException = innerException.InnerException; - } - } - } - /// /// Creates the flowslide project. /// /// The scenario. /// The soil profile probability. /// - private static FlowSlideProject CreateFlowSlideProject(Scenario scenario, SoilGeometryProbability soilProfileProbability) - { - var flowSlideProject = new FlowSlideProject(); - flowSlideProject.FlowSlideCalculationParameters.UseFlowSlideCalculation = UseFlowSlideCalculation.Global; - flowSlideProject.SurfaceLine2 = scenario.Location.LocalXZSurfaceLine2; - flowSlideProject.SoilProfile = soilProfileProbability.SoilProfile; - flowSlideProject.Soils.Clear(); - var projectSoils = new List(); - foreach (var layer in soilProfileProbability.SoilProfile.Layers) - { - if (!projectSoils.Exists(T => layer.Soil.Name.Equals(T.Name))) - { - projectSoils.Add(layer.Soil); - flowSlideProject.Soils.Add(layer.Soil); - } - } - flowSlideProject.FlowSlideCalculationParameters.CalculationParametersGeneral.Waterlevel = scenario.RiverLevel; - return flowSlideProject; - } +// private static FlowSlideProject CreateFlowSlideProject(Scenario scenario, SoilGeometryProbability soilProfileProbability) +// { +// var flowSlideProject = new FlowSlideProject(); +// flowSlideProject.FlowSlideCalculationParameters.UseFlowSlideCalculation = UseFlowSlideCalculation.Global; +// flowSlideProject.SurfaceLine2 = scenario.Location.LocalXZSurfaceLine2; +// flowSlideProject.SoilProfile = soilProfileProbability.SoilProfile; +// flowSlideProject.Soils.Clear(); +// var projectSoils = new List(); +// foreach (var layer in soilProfileProbability.SoilProfile.Layers) +// { +// if (!projectSoils.Exists(T => layer.Soil.Name.Equals(T.Name))) +// { +// projectSoils.Add(layer.Soil); +// flowSlideProject.Soils.Add(layer.Soil); +// } +// } +// flowSlideProject.FlowSlideCalculationParameters.CalculationParametersGeneral.Waterlevel = scenario.RiverLevel; +// return flowSlideProject; +// } /// /// Writes the flowslide project to file. /// /// The flow slide project. /// Name of the calculation. - private void WriteFlowSlideProjectToFile(FlowSlideProject flowSlideProject, string calculationName) - { - string flowslideCalculationDirectory = Path.Combine(CalculationBaseDirectory, @"Flowslide\"); - if (!Directory.Exists(flowslideCalculationDirectory)) - { - Directory.CreateDirectory(flowslideCalculationDirectory); - } - string filenameExtension = ".fsx"; - string fileName = calculationName + filenameExtension; - string flowslideProjectFilename = Path.Combine(flowslideCalculationDirectory, fileName); - var xmlSerializer = new XmlSerializer(); - xmlSerializer.Serialize(flowSlideProject, flowslideProjectFilename); - } +// private void WriteFlowSlideProjectToFile(FlowSlideProject flowSlideProject, string calculationName) +// { +// string flowslideCalculationDirectory = Path.Combine(CalculationBaseDirectory, @"Flowslide\"); +// if (!Directory.Exists(flowslideCalculationDirectory)) +// { +// Directory.CreateDirectory(flowslideCalculationDirectory); +// } +// string filenameExtension = ".fsx"; +// string fileName = calculationName + filenameExtension; +// string flowslideProjectFilename = Path.Combine(flowslideCalculationDirectory, fileName); +// var xmlSerializer = new XmlSerializer(); +// xmlSerializer.Serialize(flowSlideProject, flowslideProjectFilename); +// } /// /// Selects the soilProfileProbabilities for piping. @@ -688,133 +694,133 @@ /// Stability calculation /// /// - private void CalculateStabilityForScenario(Scenario scenario, int iter) - { - try - { - ConsistencyCheckStability(scenario); - Location location = scenario.Location; - var modelParametersForPLLines = new ModelParametersForPLLines - { - PenetrationLength = location.PenetrationLength, - DampingFactorPL3 = location.DampingFactorPL3, - DampingFactorPL4 = location.DampingFactorPL4, - PLLineCreationMethod = location.PLLineCreationMethod - }; - var requiredSafetyFactorStabilityInnerSlope = scenario.RequiredSafetyFactorStabilityInnerSlope ?? - location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope; - using (var stabilityCalculator = - new StabilityCalculator( - damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab, - programType, - modelParametersForPLLines, - location.TrafficLoad, - location.MinimalCircleDepth, - requiredSafetyFactorStabilityInnerSlope.Value, - mstabProgramPath, slopeWProgramPath, - location.GaugePLLines, - location.Gauges, - location.SoilbaseDB, - location.SoilList, - ProbabilisticType) - { - SelectedStabilityKernelType = damFailureMechanismeCalculationSpecification.StabilityKernelType - }) - { - //stabilityCalculator.CalculationBaseDirectory = this.CalculationBaseDirectory; - var validSoilProfileProbabilities = SelectStabilityProbabilities(scenario.Location.Segment.SoilProfileProbabilities); - if (validSoilProfileProbabilities.Count == 0) - { - throw new DamFailureMechanismeCalculatorException(String.Format("No stability profiles to calcutate for location {0}", scenario.Location.Name)); - } - int errorCount = 0; - var scenarioErrorMessages = new List(); - foreach (var soilProfileProbability in validSoilProfileProbabilities) - { - try - { - UpliftSituation? upliftSituation = scenario.GetStabilityUpliftSituation(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); - // The calculation for UpliftVan will only will done if there is Uplift - if (IsCalculationRequired(upliftSituation)) - { - stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), iter); - MStabResults? mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); - if ((mStabResults != null) && (AnalysisType.AdaptNWO == analysisType)) - { - // Store the NWO results - stabilityCalculator.NWOPhreaticAdaption = NonWaterRetainingObject.PhreaticAdaption; - var results = new NonWaterRetainingObjectResults(); - results.NwoId = NonWaterRetainingObject.NwoId; - var coordinateSystemConverter = new CoordinateSystemConverter(); - coordinateSystemConverter.DefineGlobalXYZBasedOnLine(scenario.Location.SurfaceLine2.Geometry); - results.AdaptedSurfaceLine = scenario.Location.LocalXZSurfaceLine2.FullDeepClone(); - coordinateSystemConverter.ConvertLocalXZToGlobalXYZ(results.AdaptedSurfaceLine.Geometry); - results.LocationXrdStart = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).X; - results.LocationYrdStart = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).Y; - results.LocationZrdStart = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).Z; - results.LocationXrdEnd = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).X; - results.LocationYrdEnd = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).Y; - results.LocationZrdEnd = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).Z; +// private void CalculateStabilityForScenario(Scenario scenario, int iter) +// { +// try +// { +// ConsistencyCheckStability(scenario); +// Location location = scenario.Location; +// var modelParametersForPLLines = new ModelParametersForPLLines +// { +// PenetrationLength = location.PenetrationLength, +// DampingFactorPL3 = location.DampingFactorPL3, +// DampingFactorPL4 = location.DampingFactorPL4, +// PLLineCreationMethod = location.PLLineCreationMethod +// }; +// var requiredSafetyFactorStabilityInnerSlope = scenario.RequiredSafetyFactorStabilityInnerSlope ?? +// location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope; +// using (var stabilityCalculator = +// new StabilityCalculator( +// damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab, +// programType, +// modelParametersForPLLines, +// location.TrafficLoad, +// location.MinimalCircleDepth, +// requiredSafetyFactorStabilityInnerSlope.Value, +// mstabProgramPath, slopeWProgramPath, +// location.GaugePLLines, +// location.Gauges, +// location.SoilbaseDB, +// location.SoilList, +// ProbabilisticType) +// { +// SelectedStabilityKernelType = damFailureMechanismeCalculationSpecification.StabilityKernelType +// }) +// { +// //stabilityCalculator.CalculationBaseDirectory = this.CalculationBaseDirectory; +// var validSoilProfileProbabilities = SelectStabilityProbabilities(scenario.Location.Segment.SoilProfileProbabilities); +// if (validSoilProfileProbabilities.Count == 0) +// { +// throw new DamFailureMechanismeCalculatorException(String.Format("No stability profiles to calcutate for location {0}", scenario.Location.Name)); +// } +// int errorCount = 0; +// var scenarioErrorMessages = new List(); +// foreach (var soilProfileProbability in validSoilProfileProbabilities) +// { +// try +// { +// UpliftSituation? upliftSituation = scenario.GetStabilityUpliftSituation(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); +// // The calculation for UpliftVan will only will done if there is Uplift +// if (IsCalculationRequired(upliftSituation)) +// { +// stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), iter); +// MStabResults? mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); +// if ((mStabResults != null) && (AnalysisType.AdaptNWO == analysisType)) +// { +// // Store the NWO results +// stabilityCalculator.NWOPhreaticAdaption = NonWaterRetainingObject.PhreaticAdaption; +// var results = new NonWaterRetainingObjectResults(); +// results.NwoId = NonWaterRetainingObject.NwoId; +// var coordinateSystemConverter = new CoordinateSystemConverter(); +// coordinateSystemConverter.DefineGlobalXYZBasedOnLine(scenario.Location.SurfaceLine2.Geometry); +// results.AdaptedSurfaceLine = scenario.Location.LocalXZSurfaceLine2.FullDeepClone(); +// coordinateSystemConverter.ConvertLocalXZToGlobalXYZ(results.AdaptedSurfaceLine.Geometry); +// results.LocationXrdStart = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).X; +// results.LocationYrdStart = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).Y; +// results.LocationZrdStart = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).Z; +// results.LocationXrdEnd = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).X; +// results.LocationYrdEnd = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).Y; +// results.LocationZrdEnd = results.AdaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).Z; +// +// results.MStabResults = mStabResults.Value; +// results.SoilProfileProbability = soilProfileProbability; +// scenario.NwoResults.Add(results); +// } +// } +// // assign original surfaceline to redesigned surfaceline (not for NWODesign as that would provide wrong surface line) +// if (analysisType != AnalysisType.AdaptNWO) +// { +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName, +// scenario.Location.SurfaceLine2); +// } +// } +// catch (DamFailureMechanismeCalculatorException calculatorException) +// { +// string errorMessage = "FAIL: " + calculatorException.Message; +// Exception innerException = calculatorException.InnerException; +// while (innerException != null) +// { +// errorMessage = errorMessage + ";" + innerException.Message; +// innerException = innerException.InnerException; +// } +// scenario.SetResultMessage(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName, errorMessage); +// +// calculatorException.Scenario = scenario; +// errorCount++; +// scenarioErrorMessages.Add(errorMessage); +// } +// } +// if (errorCount > 0) +// { +// string errorMessage = String.Format("{0} calculation error(s) in location {1} scenario {2}", +// errorCount, location.Name, scenario.LocationScenarioID); +// foreach (var scenarioErrorMessage in scenarioErrorMessages) +// { +// errorMessage = String.Format("{0}; {1}", errorMessage, scenarioErrorMessage); +// } +// var calculatorException = new DamFailureMechanismeCalculatorException(errorMessage) +// { +// Scenario = scenario +// }; +// throw calculatorException; +// } +// } +// } +// catch (Exception exception) +// { +// scenario.Errors.Add(exception.Message); +// Exception innerException = exception.InnerException; +// while (innerException != null) +// { +// scenario.Errors.Add(innerException.Message); +// innerException = innerException.InnerException; +// } +// throw; +// } +// } - results.MStabResults = mStabResults.Value; - results.SoilProfileProbability = soilProfileProbability; - scenario.NwoResults.Add(results); - } - } - // assign original surfaceline to redesigned surfaceline (not for NWODesign as that would provide wrong surface line) - if (analysisType != AnalysisType.AdaptNWO) - { - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName, - scenario.Location.SurfaceLine2); - } - } - catch (DamFailureMechanismeCalculatorException calculatorException) - { - string errorMessage = "FAIL: " + calculatorException.Message; - Exception innerException = calculatorException.InnerException; - while (innerException != null) - { - errorMessage = errorMessage + ";" + innerException.Message; - innerException = innerException.InnerException; - } - scenario.SetResultMessage(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName, errorMessage); - - calculatorException.Scenario = scenario; - errorCount++; - scenarioErrorMessages.Add(errorMessage); - } - } - if (errorCount > 0) - { - string errorMessage = String.Format("{0} calculation error(s) in location {1} scenario {2}", - errorCount, location.Name, scenario.LocationScenarioID); - foreach (var scenarioErrorMessage in scenarioErrorMessages) - { - errorMessage = String.Format("{0}; {1}", errorMessage, scenarioErrorMessage); - } - var calculatorException = new DamFailureMechanismeCalculatorException(errorMessage) - { - Scenario = scenario - }; - throw calculatorException; - } - } - } - catch (Exception exception) - { - scenario.Errors.Add(exception.Message); - Exception innerException = exception.InnerException; - while (innerException != null) - { - scenario.Errors.Add(innerException.Message); - innerException = innerException.InnerException; - } - throw; - } - } - /// /// Check if calculation should be done /// (In case of UpliftVan and no uplift this is not the case) @@ -839,503 +845,503 @@ /// private void ImplementNWOInSurfaceLinesForAllScenarios(Scenario scenario) { - try - { - ImplementNWOInSurfaceLine(scenario); - } - catch (Exception exception) - { - scenario.Errors.Add(exception.Message); - Exception innerException = exception.InnerException; - while (innerException != null) - { - scenario.Errors.Add(innerException.Message); - innerException = innerException.InnerException; - } - } +// try +// { +// ImplementNWOInSurfaceLine(scenario); +// } +// catch (Exception exception) +// { +// scenario.Errors.Add(exception.Message); +// Exception innerException = exception.InnerException; +// while (innerException != null) +// { +// scenario.Errors.Add(innerException.Message); +// innerException = innerException.InnerException; +// } +// } } - private void CalculateScenario(Scenario scenario, int iter) - { - switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType) - { - case FailureMechanismSystemType.StabilityInside: - case FailureMechanismSystemType.StabilityOutside: - ConsistencyCheckStabilityPerScenario(scenario); - CalculateStabilityForScenario(scenario, iter); - break; +// private void CalculateScenario(Scenario scenario, int iter) +// { +// switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType) +// { +// case FailureMechanismSystemType.StabilityInside: +// case FailureMechanismSystemType.StabilityOutside: +// ConsistencyCheckStabilityPerScenario(scenario); +// CalculateStabilityForScenario(scenario, iter); +// break; +// +// case FailureMechanismSystemType.Piping: +// CalculatePipingForScenario(scenario); +// break; +// } +// } - case FailureMechanismSystemType.Piping: - CalculatePipingForScenario(scenario); - break; - } - } - /// /// /// /// /// - private double? ImplementNWOInSurfaceLine(Scenario scenario) - { - double? safetyFactor = null; +// private double? ImplementNWOInSurfaceLine(Scenario scenario) +// { +// double? safetyFactor = null; +// +// if (scenario.Location != null) +// { +// SurfaceLine2 originalLocalXzSurfaceLine = scenario.Location.LocalXZSurfaceLine2.FullDeepClone(); +// try +// { +// // fit the non water retaining object in the current surfaceline. If it does (no longer) fit, surfaceline is returned as null and +// // the calculation is finished. The phreaticline may have to be adapted to the new surfaceline. +// +// var nwoInSurfacleLine = new NonWaterRetainingObjectInSurfaceLine(); +// nwoInSurfacleLine.NonWaterRetainingObject = NonWaterRetainingObject; +// nwoInSurfacleLine.SurfaceLine = scenario.Location.LocalXZSurfaceLine2; +// nwoInSurfacleLine.GridPosition = damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.GridPosition; +// nwoInSurfacleLine.StepSizeX = NonWaterRetainingObject.StepSizeX; +// double fitPositionX = nwoInSurfacleLine.DetermineStartLocationForNonWaterRetainingObject(true); +// if (nwoInSurfacleLine.DoesPositionXFitInSurfaceLine(fitPositionX)) +// { +// var iter = 0; +// bool doneFittingNWO = false; +// while (!doneFittingNWO) +// { +// // try to fit NWO in surfaceline. If successfull, calculate it, else this is finished. +// SurfaceLine2 localXzSurfaceLine = nwoInSurfacleLine.FitNonWaterRetainingObjectInSurfaceLine(fitPositionX); +// if (localXzSurfaceLine != null) +// { +// var validationError = localXzSurfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); +// if (validationError != null) +// { +// localXzSurfaceLine.Dispose(); +// throw new SurfaceLineException(validationError.Text); +// } +// +// scenario.Location.LocalXZSurfaceLine2.Dispose(); +// scenario.Location.LocalXZSurfaceLine2 = localXzSurfaceLine; +// // calculate with this surfaceline and store the results. +// CalculateScenario(scenario, iter); +// // Get new fitPositionX (based on stepsize X and gridposition) +// fitPositionX = nwoInSurfacleLine.DetermineNewFitPostionX(fitPositionX, true); +// iter++; +// } +// else +// { +// doneFittingNWO = true; +// } +// } +// +// if (iter > 0) +// { +// // restore the original surface line +// // Note: 'originalLocalXzSurfaceLine' is only used if now exception have occurred and +// scenario.Location.LocalXZSurfaceLine2 = originalLocalXzSurfaceLine; +// } +// else +// { +// throw new DamFailureMechanismeCalculatorException( +// "NonWaterRetainingObject does not fit within Surfaceline."); +// } +// } +// else +// { +// throw new DamFailureMechanismeCalculatorException( +// "NonWaterRetainingObject does not fit within Surfaceline."); +// } +// } +// catch (Exception e) +// { +// originalLocalXzSurfaceLine.Dispose(); // Clone has become an orphan, so dispose and discard +// +// // Add scenario if having a failure mechanism calculation exception: +// var calculatorException = e as DamFailureMechanismeCalculatorException; +// if (calculatorException != null) +// { +// calculatorException.Scenario = scenario; +// } +// throw; +// } +// } +// +// return safetyFactor; +// } - if (scenario.Location != null) - { - SurfaceLine2 originalLocalXzSurfaceLine = scenario.Location.LocalXZSurfaceLine2.FullDeepClone(); - try - { - // fit the non water retaining object in the current surfaceline. If it does (no longer) fit, surfaceline is returned as null and - // the calculation is finished. The phreaticline may have to be adapted to the new surfaceline. - - var nwoInSurfacleLine = new NonWaterRetainingObjectInSurfaceLine(); - nwoInSurfacleLine.NonWaterRetainingObject = NonWaterRetainingObject; - nwoInSurfacleLine.SurfaceLine = scenario.Location.LocalXZSurfaceLine2; - nwoInSurfacleLine.GridPosition = damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.GridPosition; - nwoInSurfacleLine.StepSizeX = NonWaterRetainingObject.StepSizeX; - double fitPositionX = nwoInSurfacleLine.DetermineStartLocationForNonWaterRetainingObject(true); - if (nwoInSurfacleLine.DoesPositionXFitInSurfaceLine(fitPositionX)) - { - var iter = 0; - bool doneFittingNWO = false; - while (!doneFittingNWO) - { - // try to fit NWO in surfaceline. If successfull, calculate it, else this is finished. - SurfaceLine2 localXzSurfaceLine = nwoInSurfacleLine.FitNonWaterRetainingObjectInSurfaceLine(fitPositionX); - if (localXzSurfaceLine != null) - { - var validationError = localXzSurfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); - if (validationError != null) - { - localXzSurfaceLine.Dispose(); - throw new SurfaceLineException(validationError.Text); - } - - scenario.Location.LocalXZSurfaceLine2.Dispose(); - scenario.Location.LocalXZSurfaceLine2 = localXzSurfaceLine; - // calculate with this surfaceline and store the results. - CalculateScenario(scenario, iter); - // Get new fitPositionX (based on stepsize X and gridposition) - fitPositionX = nwoInSurfacleLine.DetermineNewFitPostionX(fitPositionX, true); - iter++; - } - else - { - doneFittingNWO = true; - } - } - - if (iter > 0) - { - // restore the original surface line - // Note: 'originalLocalXzSurfaceLine' is only used if now exception have occurred and - scenario.Location.LocalXZSurfaceLine2 = originalLocalXzSurfaceLine; - } - else - { - throw new DamFailureMechanismeCalculatorException( - "NonWaterRetainingObject does not fit within Surfaceline."); - } - } - else - { - throw new DamFailureMechanismeCalculatorException( - "NonWaterRetainingObject does not fit within Surfaceline."); - } - } - catch (Exception e) - { - originalLocalXzSurfaceLine.Dispose(); // Clone has become an orphan, so dispose and discard - - // Add scenario if having a failure mechanism calculation exception: - var calculatorException = e as DamFailureMechanismeCalculatorException; - if (calculatorException != null) - { - calculatorException.Scenario = scenario; - } - throw; - } - } - - return safetyFactor; - } - /// /// /// /// private void RedesignSurfaceLinesForAllScenarios(Scenario scenario) { - try - { - RedesignSurfaceLine(scenario); - } - catch (Exception exception) - { - scenario.Errors.Add(exception.Message); - Exception innerException = exception.InnerException; - while (innerException != null) - { - scenario.Errors.Add(innerException.Message); - innerException = innerException.InnerException; - } - } +// try +// { +// RedesignSurfaceLine(scenario); +// } +// catch (Exception exception) +// { +// scenario.Errors.Add(exception.Message); +// Exception innerException = exception.InnerException; +// while (innerException != null) +// { +// scenario.Errors.Add(innerException.Message); +// innerException = innerException.InnerException; +// } +// } } /// /// /// /// /// - private void RedesignSurfaceLine(Scenario scenario) - { - try - { - if (scenario.Location != null) - { - SurfaceLine2 surfaceLine = scenario.Location.LocalXZSurfaceLine2.FullDeepClone(); //TODO: I really have no clue this object should be in a using clause or not... :( - if (scenario.Location.RedesignDikeHeight) - { - // Dike height adaptation +// private void RedesignSurfaceLine(Scenario scenario) +// { +// try +// { +// if (scenario.Location != null) +// { +// SurfaceLine2 surfaceLine = scenario.Location.LocalXZSurfaceLine2.FullDeepClone(); //TODO: I really have no clue this object should be in a using clause or not... :( +// if (scenario.Location.RedesignDikeHeight) +// { +// // Dike height adaptation +// +// var redesignedSurfaceLine = RedesignSurfaceLineHeight(damFailureMechanismeCalculationSpecification.FailureMechanismSystemType, +// scenario, surfaceLine); +// var validationError = redesignedSurfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); +// if (validationError != null) +// { +// redesignedSurfaceLine.Dispose(); +// throw new SurfaceLineException(validationError.Text); +// } +// +// // No error, so replace clone with redesigned surfaceline +// surfaceLine.Dispose(); +// surfaceLine = redesignedSurfaceLine; +// } +// +// if (scenario.Location.RedesignDikeShoulder) +// { +// // Shoulder and slope adaption +// double? safetyFactor = null; +// switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType) +// { +// case FailureMechanismSystemType.StabilityInside: +// case FailureMechanismSystemType.StabilityOutside: +// safetyFactor = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope; +// RedesignSurfaceLineStabilityInside(scenario, safetyFactor); +// break; +// +// case FailureMechanismSystemType.Piping: +// safetyFactor = scenario.ModelFactors.RequiredSafetyFactorPiping; +// RedesignSurfaceLinePipingShoulder(damFailureMechanismeCalculationSpecification.PipingModelType, +// scenario, ref safetyFactor, ref surfaceLine); +// break; +// case FailureMechanismSystemType.FlowSlide: +// RedesignSurfaceLineFlowSlide(scenario, safetyFactor, ref surfaceLine); +// break; +// } +// } +// } +// } +// catch (DamFailureMechanismeCalculatorException calculatorException) +// { +// calculatorException.Scenario = scenario; +// throw; +// } +// } - var redesignedSurfaceLine = RedesignSurfaceLineHeight(damFailureMechanismeCalculationSpecification.FailureMechanismSystemType, - scenario, surfaceLine); - var validationError = redesignedSurfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); - if (validationError != null) - { - redesignedSurfaceLine.Dispose(); - throw new SurfaceLineException(validationError.Text); - } - - // No error, so replace clone with redesigned surfaceline - surfaceLine.Dispose(); - surfaceLine = redesignedSurfaceLine; - } - - if (scenario.Location.RedesignDikeShoulder) - { - // Shoulder and slope adaption - double? safetyFactor = null; - switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType) - { - case FailureMechanismSystemType.StabilityInside: - case FailureMechanismSystemType.StabilityOutside: - safetyFactor = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope; - RedesignSurfaceLineStabilityInside(scenario, safetyFactor); - break; - - case FailureMechanismSystemType.Piping: - safetyFactor = scenario.ModelFactors.RequiredSafetyFactorPiping; - RedesignSurfaceLinePipingShoulder(damFailureMechanismeCalculationSpecification.PipingModelType, - scenario, ref safetyFactor, ref surfaceLine); - break; - case FailureMechanismSystemType.FlowSlide: - RedesignSurfaceLineFlowSlide(scenario, safetyFactor, ref surfaceLine); - break; - } - } - } - } - catch (DamFailureMechanismeCalculatorException calculatorException) - { - calculatorException.Scenario = scenario; - throw; - } - } - /// /// /// /// /// /// /// - private void RedesignSurfaceLinePipingShoulder(PipingModelType pipingModelType, Scenario scenario, ref double? safetyFactor, ref SurfaceLine2 surfaceLine) - { - var modelParametersForPLLines = new ModelParametersForPLLines - { - PenetrationLength = scenario.Location.PenetrationLength, - DampingFactorPL3 = scenario.Location.DampingFactorPL3, - DampingFactorPL4 = scenario.Location.DampingFactorPL4, - PLLineCreationMethod = scenario.Location.PLLineCreationMethod - }; +// private void RedesignSurfaceLinePipingShoulder(PipingModelType pipingModelType, Scenario scenario, ref double? safetyFactor, ref SurfaceLine2 surfaceLine) +// { +// var modelParametersForPLLines = new ModelParametersForPLLines +// { +// PenetrationLength = scenario.Location.PenetrationLength, +// DampingFactorPL3 = scenario.Location.DampingFactorPL3, +// DampingFactorPL4 = scenario.Location.DampingFactorPL4, +// PLLineCreationMethod = scenario.Location.PLLineCreationMethod +// }; +// +// var pipingProbabilisticParameters = new PipingProbabilisticParameters(scenario.Location.LayerHeightDistribution, +// scenario.Location.LayerHeightDeviation); +// var pipingUpliftCriterion = scenario.GetUpliftCriterionPiping(scenario.Location.ModelFactors.UpliftCriterionPiping); +// if (pipingUpliftCriterion <= 0) +// { +// throw new DamFailureMechanismeCalculatorException(String.Format("Invalid piping uplift criterion {0} for location {1} scenario {2}", +// pipingUpliftCriterion, scenario.Location.Name, scenario.LocationScenarioID)); +// } +// +// var requiredSafetyFactorPiping = 0.0; +// if (scenario.RequiredSafetyFactorPiping != null) +// { +// requiredSafetyFactorPiping = scenario.RequiredSafetyFactorPiping.Value; +// } +// if (safetyFactor != null) +// { +// requiredSafetyFactorPiping = safetyFactor.Value; +// } +// if (requiredSafetyFactorPiping <= 0) +// { +// throw new DamFailureMechanismeCalculatorException(String.Format("Invalid required safetyfactor piping {0} for location {1} scenario {2}", +// requiredSafetyFactorPiping, scenario.Location.Name, scenario.LocationScenarioID)); +// } +// PipingCalculator pipingCalculator = pipingCalculatorFactory(scenario.Location, modelParametersForPLLines, pipingModelType, +// pipingUpliftCriterion, +// requiredSafetyFactorPiping, +// pipingProbabilisticParameters); +// +// var validSoilProfileProbabilities = SelectPipingProbabilities(scenario.Location.Segment.SoilProfileProbabilities); +// if (validSoilProfileProbabilities.Count == 0) +// { +// throw new DamFailureMechanismeCalculatorException(String.Format("No piping profiles to calcutate for location {0}", scenario.Location.Name)); +// } +// foreach (var soilProfileProbability in validSoilProfileProbabilities) +// { +// try +// { +// SurfaceLine2 newSurfaceLine = surfaceLine.FullDeepClone(); +// switch (ProbabilisticType) +// { +// case ProbabilisticType.Deterministic: +// { +// var newCandidate = DetermineNewSafeSurfaceLinePipingDeterministic(scenario, soilProfileProbability, pipingCalculator, newSurfaceLine, ref safetyFactor); +// if (!ReferenceEquals(newSurfaceLine, newCandidate)) +// { +// newSurfaceLine.Dispose(); +// newSurfaceLine = newCandidate; +// } +// +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, newSurfaceLine); +// scenario.SetSafetyFactorPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, safetyFactor); +// PipingResults pipingResults = GetPipingResults(safetyFactor, pipingModelType, pipingCalculator); +// scenario.SetPipingResults(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName, pipingResults); +// break; +// } +// +// case ProbabilisticType.Probabilistic: +// case ProbabilisticType.ProbabilisticFragility: +// { +// //Todo Adapt the determination of the piping design to the way it should be (See Detrministic and functional design) +// double[] waterLevels = scenario.DetermineProperWaterlevelsForProbabilisticAdvanced(); +// double waterLevel = scenario.RiverLevel; +// +// // for test of deterministic as initialisation for probabilistic, use next line. +// // newSurfaceLine = GetNewSafeSurfaceLine(scenario, soilProfileProbability, pipingCalculator, newSurfaceLine, ref requiredSafetyFactor); +// +// bool upLiftOccured = false; +// if (ProbabilisticType == ProbabilisticType.ProbabilisticFragility) +// { +// waterLevel = waterLevels[1]; +// } +// // start by checking the uplift first (if so, a newShoulderHeight can be determined). If uplift is not an issue then +// // probability of failure = 0. If uplift is an issue, add a berm until uplift is no longer an issue. +// double? newShoulderHeight = pipingCalculator.CalculateDesignShoulderHeight(scenario.Location, newSurfaceLine, +// soilProfileProbability.SoilProfile, waterLevel); +// +// double currentShoulderHeight = 0; +// double currentShoulderWidth = 0; +// double newShoulderWidth = 0; +// double slopeFactor = 0; +// if (newShoulderHeight != null) +// { +// // Debug.Write(String.Format("New Shoulder Height {0:0.000}\n", newShoulderHeight)); +// +// // if a new shoulderheight could be found, uplift is an issue. The new found shoulderheight might however not be the correct one +// // as with this height we insert or adjust a berm. This new/adjusted berm has to be checked until uplift is no longer an issue. +// upLiftOccured = true; +// +// // Start by adding the new shoulder. Note that there might be an existing shoulder. +// var shoulderTopInside = newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); +// var dikeToeAtPolder = newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); +// if (newSurfaceLine.HasShoulderInside()) +// { +// // there was a shoulder which now has to be extended. +// currentShoulderWidth = shoulderTopInside.X - +// newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside).X; +// currentShoulderHeight = shoulderTopInside.Z - dikeToeAtPolder.Z; +// // shoulder must grow in length, it should be passed the uplift location +// newShoulderWidth = currentShoulderWidth + pipingCalculator.UpliftLocationAndResult.X - shoulderTopInside.X; +// // in height it should grow with the calculated amount. +// newShoulderHeight = newShoulderHeight.Value + currentShoulderHeight; +// } +// else +// { +// // there was no shoulder, so create one +// var dikeTopAtPolder = newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); +// slopeFactor = (dikeToeAtPolder.X - dikeTopAtPolder.X)/(dikeTopAtPolder.Z - dikeToeAtPolder.Z); +// newShoulderWidth = 0.5 + newShoulderHeight.Value*slopeFactor; +// } +// // Make sure new berm is not too small +// newShoulderHeight = Math.Max(newShoulderHeight.Value, CMinimumShoulderElevation); +// newShoulderWidth = Math.Max(newShoulderWidth, CMinimumShoulderWidth); +// currentShoulderWidth = newShoulderWidth; +// currentShoulderHeight = newShoulderHeight.Value; +// +// bool finished = false; +// double maxShoulderLevel = CalculateMaximumShoulderLevel(newSurfaceLine, 1.0); // no limit to height of shoulder +// while ((newShoulderHeight != null) && (!finished)) +// { +// var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(newSurfaceLine, scenario.Location); +// surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; +// newSurfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(newShoulderWidth, newShoulderHeight.Value, true); +// newShoulderHeight = pipingCalculator.CalculateDesignShoulderHeight(scenario.Location, newSurfaceLine, +// soilProfileProbability.SoilProfile, waterLevel); +// finished = (pipingCalculator.UpliftLocationAndResult.X > shoulderTopInside.X); +// if (newShoulderHeight != null && (!finished)) +// { +// // make sure new height is at least cMinimumShoulderExtraElevation higher +// if (newShoulderHeight.Value < CMinimumShoulderExtraElevation) +// { +// newShoulderHeight = currentShoulderHeight + CMinimumShoulderExtraElevation; +// } +// else +// { +// newShoulderHeight = currentShoulderHeight + newShoulderHeight.Value; +// } +// // shoulder must grow in length, it should be passed the uplift location and at least the minimum grow value +// newShoulderWidth = currentShoulderWidth + CMinimumShoulderExtraWidth; +// currentShoulderWidth = currentShoulderWidth + pipingCalculator.UpliftLocationAndResult.X - +// shoulderTopInside.X; +// newShoulderWidth = Math.Max(currentShoulderWidth, newShoulderWidth); +// +// currentShoulderWidth = newShoulderWidth; +// currentShoulderHeight = newShoulderHeight.Value; +// } +// } +// } +// +// // if no shoulder needed (i.e. when no uplift occurs) then failure probability is always cDefaultMinReturnValue = 0.0 +// double? failureProbability = PipingCalculator.cDefaultMinReturnValue; +// if (upLiftOccured) +// { +// // Uplift occured, so calculate failureProbability +// if (ProbabilisticType == ProbabilisticType.Probabilistic) +// { +// var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); +// waterLevelProbabilistic.Mean = scenario.RiverLevel; +// failureProbability = pipingCalculator.CalculatePipingFailureProbability(scenario.Location, newSurfaceLine, +// soilProfileProbability.SoilProfile, waterLevelProbabilistic); +// } +// else +// { +// failureProbability = CalculatePipingFailureProbabilityAdvanced(pipingCalculator, scenario, soilProfileProbability, +// newSurfaceLine); +// } +// +// if (failureProbability != null) +// { +// int iterationIndex = 1; +// bool isRedesignRequired = (failureProbability.Value > scenario.ModelFactors.RequiredProbabilityOfFailurePiping); +// +// double maxShoulderLevel = CalculateMaximumShoulderLevel(newSurfaceLine, 1.0); // no limit to height of shoulder +// while (isRedesignRequired && newSurfaceLine != null) +// { +// // Debug.Write(String.Format("Iteration {0} failureProbability {1:0.0000000000}, currentShoulderWidth {2:0.000}, currentShoulderHeight {3:0.000}\n", iterationIndex, failureProbability, currentShoulderWidth, currentShoulderHeight)); +// iterationIndex++; +// currentShoulderWidth = currentShoulderWidth + 1; +// // Due to different calculation types, raise the shoulder too next to making it wider. +// currentShoulderHeight = currentShoulderHeight + CMinimumShoulderExtraElevation; +// var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(newSurfaceLine, scenario.Location); +// surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; +// newSurfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(currentShoulderWidth, currentShoulderHeight, true); +// if (ProbabilisticType == ProbabilisticType.Probabilistic) +// { +// var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); +// waterLevelProbabilistic.Mean = scenario.RiverLevel; +// failureProbability = pipingCalculator.CalculatePipingFailureProbability( +// scenario.Location, newSurfaceLine, +// soilProfileProbability.SoilProfile, waterLevelProbabilistic); +// } +// else +// { +// failureProbability = CalculatePipingFailureProbabilityAdvanced(pipingCalculator, scenario, +// soilProfileProbability, newSurfaceLine); +// } +// +// if (failureProbability != null) +// { +// isRedesignRequired = (failureProbability.Value > scenario.ModelFactors.RequiredProbabilityOfFailurePiping); +// } +// else +// { +// isRedesignRequired = true; +// } +// if (iterationIndex >= PipingRedesingMaxIterations) +// { +// // #BKA: vraag voor Ray set the results in case of failure too to provide feedback. (of niet Tom???) Voorlopig even niet. Ray was net naar huis dus nog navragen. +// // scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, +// // failureProbability); +// // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, +// // newSurfaceLine); +// throw new MaximumRedesignIterationsReachedException(); +// } +// } +// } +// } +// if (failureProbability != null) +// { +// scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, +// failureProbability); +// } +// else +// { +// scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, +// 999); +// } +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, newSurfaceLine); +// break; +// } +// } +// +// scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, "Succes"); +// } +// catch (Exception exception) +// { +// string errorMessage = String.Format("Location '{0}', Soilprofile '{1}': {2}", +// scenario.Location.Name, soilProfileProbability.SoilGeometryName, exception.Message); +// PipingResults pipingResults = GetPipingResults(-1, pipingModelType, pipingCalculator); +// scenario.SetPipingResults(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, pipingResults); +// scenario.SetSafetyFactorPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, -1); +// scenario.Errors.Add("FAIL: " + errorMessage); +// scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, "FAIL: " + errorMessage); +// } +// } +// } - var pipingProbabilisticParameters = new PipingProbabilisticParameters(scenario.Location.LayerHeightDistribution, - scenario.Location.LayerHeightDeviation); - var pipingUpliftCriterion = scenario.GetUpliftCriterionPiping(scenario.Location.ModelFactors.UpliftCriterionPiping); - if (pipingUpliftCriterion <= 0) - { - throw new DamFailureMechanismeCalculatorException(String.Format("Invalid piping uplift criterion {0} for location {1} scenario {2}", - pipingUpliftCriterion, scenario.Location.Name, scenario.LocationScenarioID)); - } +// private PipingResults GetPipingResults(double? safetyFactor, PipingModelType pipingModelType, PipingCalculator pipingCalculator) +// { +// var pipingResults = new PipingResults(); +// switch (pipingModelType) +// { +// case PipingModelType.Bligh: +// pipingResults.BlighHCritical = pipingCalculator.HCritical; +// pipingResults.BlighPipingFactor = safetyFactor; +// break; +// case PipingModelType.Sellmeijer: +// pipingResults.SellmeijerHCritical = pipingCalculator.HCritical; +// pipingResults.SellmeijerPipingFactor = safetyFactor; +// break; +// case PipingModelType.Sellmeijer2Forces: +// pipingResults.Sellmeijer2ForcesHCritical = pipingCalculator.HCritical; +// pipingResults.Sellmeijer2ForcesPipingFactor = safetyFactor; +// break; +// case PipingModelType.Sellmeijer4Forces: +// pipingResults.Sellmeijer4ForcesHCritical = pipingCalculator.HCritical; +// pipingResults.Sellmeijer4ForcesPipingFactor = safetyFactor; +// break; +// case PipingModelType.Wti2017: +// pipingResults.Wti2017HCritical = pipingCalculator.HCritical; +// pipingResults.Wti2017PipingFactor = safetyFactor; +// break; +// } +// return pipingResults; +// } - var requiredSafetyFactorPiping = 0.0; - if (scenario.RequiredSafetyFactorPiping != null) - { - requiredSafetyFactorPiping = scenario.RequiredSafetyFactorPiping.Value; - } - if (safetyFactor != null) - { - requiredSafetyFactorPiping = safetyFactor.Value; - } - if (requiredSafetyFactorPiping <= 0) - { - throw new DamFailureMechanismeCalculatorException(String.Format("Invalid required safetyfactor piping {0} for location {1} scenario {2}", - requiredSafetyFactorPiping, scenario.Location.Name, scenario.LocationScenarioID)); - } - PipingCalculator pipingCalculator = pipingCalculatorFactory(scenario.Location, modelParametersForPLLines, pipingModelType, - pipingUpliftCriterion, - requiredSafetyFactorPiping, - pipingProbabilisticParameters); - - var validSoilProfileProbabilities = SelectPipingProbabilities(scenario.Location.Segment.SoilProfileProbabilities); - if (validSoilProfileProbabilities.Count == 0) - { - throw new DamFailureMechanismeCalculatorException(String.Format("No piping profiles to calcutate for location {0}", scenario.Location.Name)); - } - foreach (var soilProfileProbability in validSoilProfileProbabilities) - { - try - { - SurfaceLine2 newSurfaceLine = surfaceLine.FullDeepClone(); - switch (ProbabilisticType) - { - case ProbabilisticType.Deterministic: - { - var newCandidate = DetermineNewSafeSurfaceLinePipingDeterministic(scenario, soilProfileProbability, pipingCalculator, newSurfaceLine, ref safetyFactor); - if (!ReferenceEquals(newSurfaceLine, newCandidate)) - { - newSurfaceLine.Dispose(); - newSurfaceLine = newCandidate; - } - - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, newSurfaceLine); - scenario.SetSafetyFactorPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, safetyFactor); - PipingResults pipingResults = GetPipingResults(safetyFactor, pipingModelType, pipingCalculator); - scenario.SetPipingResults(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName, pipingResults); - break; - } - - case ProbabilisticType.Probabilistic: - case ProbabilisticType.ProbabilisticFragility: - { - //Todo Adapt the determination of the piping design to the way it should be (See Detrministic and functional design) - double[] waterLevels = scenario.DetermineProperWaterlevelsForProbabilisticAdvanced(); - double waterLevel = scenario.RiverLevel; - - // for test of deterministic as initialisation for probabilistic, use next line. - // newSurfaceLine = GetNewSafeSurfaceLine(scenario, soilProfileProbability, pipingCalculator, newSurfaceLine, ref requiredSafetyFactor); - - bool upLiftOccured = false; - if (ProbabilisticType == ProbabilisticType.ProbabilisticFragility) - { - waterLevel = waterLevels[1]; - } - // start by checking the uplift first (if so, a newShoulderHeight can be determined). If uplift is not an issue then - // probability of failure = 0. If uplift is an issue, add a berm until uplift is no longer an issue. - double? newShoulderHeight = pipingCalculator.CalculateDesignShoulderHeight(scenario.Location, newSurfaceLine, - soilProfileProbability.SoilProfile, waterLevel); - - double currentShoulderHeight = 0; - double currentShoulderWidth = 0; - double newShoulderWidth = 0; - double slopeFactor = 0; - if (newShoulderHeight != null) - { - // Debug.Write(String.Format("New Shoulder Height {0:0.000}\n", newShoulderHeight)); - - // if a new shoulderheight could be found, uplift is an issue. The new found shoulderheight might however not be the correct one - // as with this height we insert or adjust a berm. This new/adjusted berm has to be checked until uplift is no longer an issue. - upLiftOccured = true; - - // Start by adding the new shoulder. Note that there might be an existing shoulder. - var shoulderTopInside = newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); - var dikeToeAtPolder = newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); - if (newSurfaceLine.HasShoulderInside()) - { - // there was a shoulder which now has to be extended. - currentShoulderWidth = shoulderTopInside.X - - newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside).X; - currentShoulderHeight = shoulderTopInside.Z - dikeToeAtPolder.Z; - // shoulder must grow in length, it should be passed the uplift location - newShoulderWidth = currentShoulderWidth + pipingCalculator.UpliftLocationAndResult.X - shoulderTopInside.X; - // in height it should grow with the calculated amount. - newShoulderHeight = newShoulderHeight.Value + currentShoulderHeight; - } - else - { - // there was no shoulder, so create one - var dikeTopAtPolder = newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); - slopeFactor = (dikeToeAtPolder.X - dikeTopAtPolder.X)/(dikeTopAtPolder.Z - dikeToeAtPolder.Z); - newShoulderWidth = 0.5 + newShoulderHeight.Value*slopeFactor; - } - // Make sure new berm is not too small - newShoulderHeight = Math.Max(newShoulderHeight.Value, CMinimumShoulderElevation); - newShoulderWidth = Math.Max(newShoulderWidth, CMinimumShoulderWidth); - currentShoulderWidth = newShoulderWidth; - currentShoulderHeight = newShoulderHeight.Value; - - bool finished = false; - double maxShoulderLevel = CalculateMaximumShoulderLevel(newSurfaceLine, 1.0); // no limit to height of shoulder - while ((newShoulderHeight != null) && (!finished)) - { - var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(newSurfaceLine, scenario.Location); - surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; - newSurfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(newShoulderWidth, newShoulderHeight.Value, true); - newShoulderHeight = pipingCalculator.CalculateDesignShoulderHeight(scenario.Location, newSurfaceLine, - soilProfileProbability.SoilProfile, waterLevel); - finished = (pipingCalculator.UpliftLocationAndResult.X > shoulderTopInside.X); - if (newShoulderHeight != null && (!finished)) - { - // make sure new height is at least cMinimumShoulderExtraElevation higher - if (newShoulderHeight.Value < CMinimumShoulderExtraElevation) - { - newShoulderHeight = currentShoulderHeight + CMinimumShoulderExtraElevation; - } - else - { - newShoulderHeight = currentShoulderHeight + newShoulderHeight.Value; - } - // shoulder must grow in length, it should be passed the uplift location and at least the minimum grow value - newShoulderWidth = currentShoulderWidth + CMinimumShoulderExtraWidth; - currentShoulderWidth = currentShoulderWidth + pipingCalculator.UpliftLocationAndResult.X - - shoulderTopInside.X; - newShoulderWidth = Math.Max(currentShoulderWidth, newShoulderWidth); - - currentShoulderWidth = newShoulderWidth; - currentShoulderHeight = newShoulderHeight.Value; - } - } - } - - // if no shoulder needed (i.e. when no uplift occurs) then failure probability is always cDefaultMinReturnValue = 0.0 - double? failureProbability = PipingCalculator.cDefaultMinReturnValue; - if (upLiftOccured) - { - // Uplift occured, so calculate failureProbability - if (ProbabilisticType == ProbabilisticType.Probabilistic) - { - var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); - waterLevelProbabilistic.Mean = scenario.RiverLevel; - failureProbability = pipingCalculator.CalculatePipingFailureProbability(scenario.Location, newSurfaceLine, - soilProfileProbability.SoilProfile, waterLevelProbabilistic); - } - else - { - failureProbability = CalculatePipingFailureProbabilityAdvanced(pipingCalculator, scenario, soilProfileProbability, - newSurfaceLine); - } - - if (failureProbability != null) - { - int iterationIndex = 1; - bool isRedesignRequired = (failureProbability.Value > scenario.ModelFactors.RequiredProbabilityOfFailurePiping); - - double maxShoulderLevel = CalculateMaximumShoulderLevel(newSurfaceLine, 1.0); // no limit to height of shoulder - while (isRedesignRequired && newSurfaceLine != null) - { - // Debug.Write(String.Format("Iteration {0} failureProbability {1:0.0000000000}, currentShoulderWidth {2:0.000}, currentShoulderHeight {3:0.000}\n", iterationIndex, failureProbability, currentShoulderWidth, currentShoulderHeight)); - iterationIndex++; - currentShoulderWidth = currentShoulderWidth + 1; - // Due to different calculation types, raise the shoulder too next to making it wider. - currentShoulderHeight = currentShoulderHeight + CMinimumShoulderExtraElevation; - var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(newSurfaceLine, scenario.Location); - surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; - newSurfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(currentShoulderWidth, currentShoulderHeight, true); - if (ProbabilisticType == ProbabilisticType.Probabilistic) - { - var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); - waterLevelProbabilistic.Mean = scenario.RiverLevel; - failureProbability = pipingCalculator.CalculatePipingFailureProbability( - scenario.Location, newSurfaceLine, - soilProfileProbability.SoilProfile, waterLevelProbabilistic); - } - else - { - failureProbability = CalculatePipingFailureProbabilityAdvanced(pipingCalculator, scenario, - soilProfileProbability, newSurfaceLine); - } - - if (failureProbability != null) - { - isRedesignRequired = (failureProbability.Value > scenario.ModelFactors.RequiredProbabilityOfFailurePiping); - } - else - { - isRedesignRequired = true; - } - if (iterationIndex >= PipingRedesingMaxIterations) - { - // #BKA: vraag voor Ray set the results in case of failure too to provide feedback. (of niet Tom???) Voorlopig even niet. Ray was net naar huis dus nog navragen. - // scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, - // failureProbability); - // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, - // newSurfaceLine); - throw new MaximumRedesignIterationsReachedException(); - } - } - } - } - if (failureProbability != null) - { - scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, - failureProbability); - } - else - { - scenario.SetFailureProbabilityPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, - 999); - } - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, newSurfaceLine); - break; - } - } - - scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, "Succes"); - } - catch (Exception exception) - { - string errorMessage = String.Format("Location '{0}', Soilprofile '{1}': {2}", - scenario.Location.Name, soilProfileProbability.SoilGeometryName, exception.Message); - PipingResults pipingResults = GetPipingResults(-1, pipingModelType, pipingCalculator); - scenario.SetPipingResults(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, pipingResults); - scenario.SetSafetyFactorPiping(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, -1); - scenario.Errors.Add("FAIL: " + errorMessage); - scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, "FAIL: " + errorMessage); - } - } - } - - private PipingResults GetPipingResults(double? safetyFactor, PipingModelType pipingModelType, PipingCalculator pipingCalculator) - { - var pipingResults = new PipingResults(); - switch (pipingModelType) - { - case PipingModelType.Bligh: - pipingResults.BlighHCritical = pipingCalculator.HCritical; - pipingResults.BlighPipingFactor = safetyFactor; - break; - case PipingModelType.Sellmeijer: - pipingResults.SellmeijerHCritical = pipingCalculator.HCritical; - pipingResults.SellmeijerPipingFactor = safetyFactor; - break; - case PipingModelType.Sellmeijer2Forces: - pipingResults.Sellmeijer2ForcesHCritical = pipingCalculator.HCritical; - pipingResults.Sellmeijer2ForcesPipingFactor = safetyFactor; - break; - case PipingModelType.Sellmeijer4Forces: - pipingResults.Sellmeijer4ForcesHCritical = pipingCalculator.HCritical; - pipingResults.Sellmeijer4ForcesPipingFactor = safetyFactor; - break; - case PipingModelType.Wti2017: - pipingResults.Wti2017HCritical = pipingCalculator.HCritical; - pipingResults.Wti2017PipingFactor = safetyFactor; - break; - } - return pipingResults; - } - /// /// Ensures that the points on the surface line are never more than cDiff (0.5) apart. /// @@ -1367,79 +1373,79 @@ return newLine; } - private SurfaceLine2 DetermineNewSafeSurfaceLinePipingDeterministic(Scenario scenario, SoilGeometryProbability soilProfileProbability, PipingCalculator pipingCalculator, SurfaceLine2 surfaceLine, ref double? safetyFactor) - { - double orgShoulderLength = surfaceLine.DetermineShoulderWidth(); - double orgShoulderHeight = surfaceLine.DetermineShoulderHeight(); - double desiredShoulderLength = orgShoulderLength; - double desiredShoulderHeight = orgShoulderHeight; - double oldDesiredShoulderLength = orgShoulderLength; - double oldDesiredShoulderHeight = orgShoulderHeight; +// private SurfaceLine2 DetermineNewSafeSurfaceLinePipingDeterministic(Scenario scenario, SoilGeometryProbability soilProfileProbability, PipingCalculator pipingCalculator, SurfaceLine2 surfaceLine, ref double? safetyFactor) +// { +// double orgShoulderLength = surfaceLine.DetermineShoulderWidth(); +// double orgShoulderHeight = surfaceLine.DetermineShoulderHeight(); +// double desiredShoulderLength = orgShoulderLength; +// double desiredShoulderHeight = orgShoulderHeight; +// double oldDesiredShoulderLength = orgShoulderLength; +// double oldDesiredShoulderHeight = orgShoulderHeight; +// +// GeometryPoint startSurfacePoint = surfaceLine.GetDikeToeInward(); +// +// IEnumerable relevantSurfacePointsList = from GeometryPoint point in surfaceLine.Geometry.Points +// where point.X >= startSurfacePoint.X +// orderby point.X ascending +// select point; +// relevantSurfacePointsList = GetCheckedSurfaceLine(relevantSurfacePointsList); +// int pointCount = 0; +// foreach (var point in relevantSurfacePointsList) +// { +// pointCount++; +// // Determine calculation filename to output piping calculation file +// //pipingCalculator.PipingCalculationDirectory = GetPipingCalculationBaseDirectory(); +// //string fileNameCalculation =String.Format("Calc({0})_Loc({1})_Pro({2})_Pnt({3}))", +// // pipingCalculator.CalculationModelIdentifier, scenario.Location.Name, soilProfileProbability.SoilProfile.Name, pointCount.ToString("d4")); ; +// //pipingCalculator.FilenameCalculation = Path.Combine(pipingCalculator.PipingCalculationDirectory, fileNameCalculation); +// +// // Calculate the piping design at the given point. This returns the required adaption (berm length and height) if any. +// var pipingDesign = pipingCalculator.CalculateDesignAtPoint(scenario.Location, surfaceLine, +// soilProfileProbability.SoilProfile, +// scenario.RiverLevel, point); +// if (pipingDesign != null) +// { +// // Piping is an issue so adapt the surfaceline for it +// desiredShoulderLength = pipingDesign.PipingLengthFromToe; +// desiredShoulderLength = Math.Max(desiredShoulderLength, oldDesiredShoulderLength); +// oldDesiredShoulderLength = desiredShoulderLength; +// // shoulder height is height above surfacelevel!! +// desiredShoulderHeight = pipingDesign.ShoulderHeightFromToe; +// desiredShoulderHeight = Math.Max(desiredShoulderHeight, oldDesiredShoulderHeight); +// oldDesiredShoulderHeight = desiredShoulderHeight; +// } +// } +// if (desiredShoulderLength > 0) +// { +// desiredShoulderLength = Math.Max(desiredShoulderLength, CMinimumShoulderWidth); +// } +// if (desiredShoulderLength > 0) +// { +// desiredShoulderHeight = Math.Max(desiredShoulderHeight, CMinimumShoulderElevation); +// } +// bool isNewShoulderSameAsOriginal = ((Math.Abs(desiredShoulderLength - orgShoulderLength) < CToleranceShoulderChanges) && +// (Math.Abs(desiredShoulderHeight - orgShoulderHeight) < CToleranceShoulderChanges)); +// if (isNewShoulderSameAsOriginal) +// { +// return surfaceLine; +// } +// else +// { +// // Adapt the surfaceline for the finally required shoulder dimensions. +// double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, 1.0); // no limit to height of shoulder +// var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, scenario.Location); +// surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; +// SurfaceLine2 newSurfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(desiredShoulderLength, desiredShoulderHeight, true); +// +// safetyFactor = pipingCalculator.CalculatePipingFactor(scenario.Location, newSurfaceLine, soilProfileProbability.SoilProfile, scenario.RiverLevel); +// if (safetyFactor < scenario.RequiredSafetyFactorPiping) +// { +// throw new DamFailureMechanismeCalculatorException("Deterministic Design: Piping is not safe yet."); +// } +// return newSurfaceLine; +// } +// } - GeometryPoint startSurfacePoint = surfaceLine.GetDikeToeInward(); - - IEnumerable relevantSurfacePointsList = from GeometryPoint point in surfaceLine.Geometry.Points - where point.X >= startSurfacePoint.X - orderby point.X ascending - select point; - relevantSurfacePointsList = GetCheckedSurfaceLine(relevantSurfacePointsList); - int pointCount = 0; - foreach (var point in relevantSurfacePointsList) - { - pointCount++; - // Determine calculation filename to output piping calculation file - //pipingCalculator.PipingCalculationDirectory = GetPipingCalculationBaseDirectory(); - //string fileNameCalculation =String.Format("Calc({0})_Loc({1})_Pro({2})_Pnt({3}))", - // pipingCalculator.CalculationModelIdentifier, scenario.Location.Name, soilProfileProbability.SoilProfile.Name, pointCount.ToString("d4")); ; - //pipingCalculator.FilenameCalculation = Path.Combine(pipingCalculator.PipingCalculationDirectory, fileNameCalculation); - - // Calculate the piping design at the given point. This returns the required adaption (berm length and height) if any. - var pipingDesign = pipingCalculator.CalculateDesignAtPoint(scenario.Location, surfaceLine, - soilProfileProbability.SoilProfile, - scenario.RiverLevel, point); - if (pipingDesign != null) - { - // Piping is an issue so adapt the surfaceline for it - desiredShoulderLength = pipingDesign.PipingLengthFromToe; - desiredShoulderLength = Math.Max(desiredShoulderLength, oldDesiredShoulderLength); - oldDesiredShoulderLength = desiredShoulderLength; - // shoulder height is height above surfacelevel!! - desiredShoulderHeight = pipingDesign.ShoulderHeightFromToe; - desiredShoulderHeight = Math.Max(desiredShoulderHeight, oldDesiredShoulderHeight); - oldDesiredShoulderHeight = desiredShoulderHeight; - } - } - if (desiredShoulderLength > 0) - { - desiredShoulderLength = Math.Max(desiredShoulderLength, CMinimumShoulderWidth); - } - if (desiredShoulderLength > 0) - { - desiredShoulderHeight = Math.Max(desiredShoulderHeight, CMinimumShoulderElevation); - } - bool isNewShoulderSameAsOriginal = ((Math.Abs(desiredShoulderLength - orgShoulderLength) < CToleranceShoulderChanges) && - (Math.Abs(desiredShoulderHeight - orgShoulderHeight) < CToleranceShoulderChanges)); - if (isNewShoulderSameAsOriginal) - { - return surfaceLine; - } - else - { - // Adapt the surfaceline for the finally required shoulder dimensions. - double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, 1.0); // no limit to height of shoulder - var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, scenario.Location); - surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; - SurfaceLine2 newSurfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(desiredShoulderLength, desiredShoulderHeight, true); - - safetyFactor = pipingCalculator.CalculatePipingFactor(scenario.Location, newSurfaceLine, soilProfileProbability.SoilProfile, scenario.RiverLevel); - if (safetyFactor < scenario.RequiredSafetyFactorPiping) - { - throw new DamFailureMechanismeCalculatorException("Deterministic Design: Piping is not safe yet."); - } - return newSurfaceLine; - } - } - /// /// Create the initial geometry to be used to determine layers for embankment for design /// @@ -1449,97 +1455,97 @@ /// /// /// - private void CreateInitialGeometry(Scenario scenario, StabilityCalculator stabilityCalculator, SoilGeometryProbability soilProfileProbability, SurfaceLine2 surfaceLine, out String initialgeometryFile) - { - const int IterationIndex = -1; +// private void CreateInitialGeometry(Scenario scenario, StabilityCalculator stabilityCalculator, SoilGeometryProbability soilProfileProbability, SurfaceLine2 surfaceLine, out String initialgeometryFile) +// { +// const int IterationIndex = -1; +// +// initialgeometryFile = StabilityCalculator.DetermineCalculationFilename(scenario.Location.Name, scenario.LocationScenarioID, soilProfileProbability.SoilGeometryName, IterationIndex); +// initialgeometryFile = initialgeometryFile + stabilityCalculator.GetFilenameExtension(); +// initialgeometryFile = Path.Combine(stabilityCalculator.GetStabilityCalculationDirectory(), initialgeometryFile); +// double riverLevel = 0.5*(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).Z + +// surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z); +// string soilgeometry2DFilename = null; +// if (soilProfileProbability.SoilGeometry2DName != null) +// { +// soilgeometry2DFilename = +// Path.GetFullPath(Path.Combine(DamProject.ProjectMap, Path.Combine(scenario.Location.MapForSoilGeometries2D, soilProfileProbability.SoilGeometry2DName))); +// } +// XDocument mstabXML = stabilityCalculator.CreateMStabXmlDoc(initialgeometryFile, scenario, soilProfileProbability.SoilProfile, +// soilgeometry2DFilename, riverLevel, null, surfaceLine); +// mstabXML.Save(initialgeometryFile + ".xml"); +// var stabilityServiceAgent = new StabilityServiceAgent(); +// stabilityServiceAgent.CreateProjectFile(mstabXML.ToString()); +// if (!File.Exists(initialgeometryFile)) +// { +// throw new DamFailureMechanismeCalculatorException("Initial geometry file (sti) is not created."); +// } +// } - initialgeometryFile = StabilityCalculator.DetermineCalculationFilename(scenario.Location.Name, scenario.LocationScenarioID, soilProfileProbability.SoilGeometryName, IterationIndex); - initialgeometryFile = initialgeometryFile + stabilityCalculator.GetFilenameExtension(); - initialgeometryFile = Path.Combine(stabilityCalculator.GetStabilityCalculationDirectory(), initialgeometryFile); - double riverLevel = 0.5*(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).Z + - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z); - string soilgeometry2DFilename = null; - if (soilProfileProbability.SoilGeometry2DName != null) - { - soilgeometry2DFilename = - Path.GetFullPath(Path.Combine(DamProject.ProjectMap, Path.Combine(scenario.Location.MapForSoilGeometries2D, soilProfileProbability.SoilGeometry2DName))); - } - XDocument mstabXML = stabilityCalculator.CreateMStabXmlDoc(initialgeometryFile, scenario, soilProfileProbability.SoilProfile, - soilgeometry2DFilename, riverLevel, null, surfaceLine); - mstabXML.Save(initialgeometryFile + ".xml"); - var stabilityServiceAgent = new StabilityServiceAgent(); - stabilityServiceAgent.CreateProjectFile(mstabXML.ToString()); - if (!File.Exists(initialgeometryFile)) - { - throw new DamFailureMechanismeCalculatorException("Initial geometry file (sti) is not created."); - } - } - /// /// Redesigns the surface line for mechanism stability inside. /// /// The scenario. /// The safety factor. - private void RedesignSurfaceLineStabilityInside(Scenario scenario, double? requiredSafetyFactor) - { - Location location = scenario.Location; - var modelParametersForPLLines = new ModelParametersForPLLines - { - PenetrationLength = location.PenetrationLength, - DampingFactorPL3 = location.DampingFactorPL3, - DampingFactorPL4 = location.DampingFactorPL4, - PLLineCreationMethod = location.PLLineCreationMethod - }; - using (var stabilityCalculator = - new StabilityCalculator(damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab, - programType, - modelParametersForPLLines, - location.TrafficLoad, - location.MinimalCircleDepth, - requiredSafetyFactor.Value, - mstabProgramPath, - slopeWProgramPath, - location.GaugePLLines, - location.Gauges, - location.SoilbaseDB, - location.SoilList, - ProbabilisticType) - { - SelectedStabilityKernelType = damFailureMechanismeCalculationSpecification.StabilityKernelType - }) - { - var validSoilProfileProbabilities = SelectStabilityProbabilities(scenario.Location.Segment.SoilProfileProbabilities); - if (validSoilProfileProbabilities.Count == 0) - { - throw new DamFailureMechanismeCalculatorException(String.Format("No stability profiles to calcutate for location {0}", scenario.Location.Name)); - } - foreach (var soilProfileProbability in validSoilProfileProbabilities) - { - // The calculation for UpliftVan will only will done if there is Uplift - UpliftSituation? upliftSituation = scenario.GetStabilityUpliftSituation(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); - if (IsCalculationRequired(upliftSituation)) - { - switch (scenario.Location.StabilityDesignMethod) - { - // Bij WTIkernel is het soilprofile2D nog null in de soilProfileProbability en daarom gat Adapt Geometry fout. -// nagaan bij classic Delphi of dat daar ook leeg is. Daarnaast is het probleem groter. Je moet denk ik de geometrie geheel regenereren NADAT de surfaceline -// is aangepast. Dan moet de soilprofile2D goed gezet worden (en ook de sti + naam sti!?!?!?! uitzoeken!) op de nieuwe 2Dgeom. En die moet goed in de kernel terecht komen. -// Dus dat kan nog niet hier want de nieuwe surfaceline is nog niet bekend. Gebruik maken van de surf2dprof combiner!! - case StabilityDesignMethod.OptimizedSlopeAndShoulderAdaption: - { - RedesignCombinedSlopeAdaptionAndShoulderAdaption(scenario, stabilityCalculator, soilProfileProbability); - break; - } - case StabilityDesignMethod.SlopeAdaptionBeforeShoulderAdaption: - { - RedesignFirstSlopeAdaptionThenShoulderAdaption(scenario, stabilityCalculator, soilProfileProbability); - break; - } - } - } - } - } - } +// private void RedesignSurfaceLineStabilityInside(Scenario scenario, double? requiredSafetyFactor) +// { +// Location location = scenario.Location; +// var modelParametersForPLLines = new ModelParametersForPLLines +// { +// PenetrationLength = location.PenetrationLength, +// DampingFactorPL3 = location.DampingFactorPL3, +// DampingFactorPL4 = location.DampingFactorPL4, +// PLLineCreationMethod = location.PLLineCreationMethod +// }; +// using (var stabilityCalculator = +// new StabilityCalculator(damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab, +// programType, +// modelParametersForPLLines, +// location.TrafficLoad, +// location.MinimalCircleDepth, +// requiredSafetyFactor.Value, +// mstabProgramPath, +// slopeWProgramPath, +// location.GaugePLLines, +// location.Gauges, +// location.SoilbaseDB, +// location.SoilList, +// ProbabilisticType) +// { +// SelectedStabilityKernelType = damFailureMechanismeCalculationSpecification.StabilityKernelType +// }) +// { +// var validSoilProfileProbabilities = SelectStabilityProbabilities(scenario.Location.Segment.SoilProfileProbabilities); +// if (validSoilProfileProbabilities.Count == 0) +// { +// throw new DamFailureMechanismeCalculatorException(String.Format("No stability profiles to calcutate for location {0}", scenario.Location.Name)); +// } +// foreach (var soilProfileProbability in validSoilProfileProbabilities) +// { +// // The calculation for UpliftVan will only will done if there is Uplift +// UpliftSituation? upliftSituation = scenario.GetStabilityUpliftSituation(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); +// if (IsCalculationRequired(upliftSituation)) +// { +// switch (scenario.Location.StabilityDesignMethod) +// { +// // Bij WTIkernel is het soilprofile2D nog null in de soilProfileProbability en daarom gat Adapt Geometry fout. +//// nagaan bij classic Delphi of dat daar ook leeg is. Daarnaast is het probleem groter. Je moet denk ik de geometrie geheel regenereren NADAT de surfaceline +//// is aangepast. Dan moet de soilprofile2D goed gezet worden (en ook de sti + naam sti!?!?!?! uitzoeken!) op de nieuwe 2Dgeom. En die moet goed in de kernel terecht komen. +//// Dus dat kan nog niet hier want de nieuwe surfaceline is nog niet bekend. Gebruik maken van de surf2dprof combiner!! +// case StabilityDesignMethod.OptimizedSlopeAndShoulderAdaption: +// { +// RedesignCombinedSlopeAdaptionAndShoulderAdaption(scenario, stabilityCalculator, soilProfileProbability); +// break; +// } +// case StabilityDesignMethod.SlopeAdaptionBeforeShoulderAdaption: +// { +// RedesignFirstSlopeAdaptionThenShoulderAdaption(scenario, stabilityCalculator, soilProfileProbability); +// break; +// } +// } +// } +// } +// } +// } /// /// Redesign for Stability: @@ -1552,145 +1558,145 @@ /// /// /// - private void RedesignCombinedSlopeAdaptionAndShoulderAdaption(Scenario scenario, StabilityCalculator stabilityCalculator, - SoilGeometryProbability soilProfileProbability) - { - Location location = scenario.Location; - double requiredSafetyFactor = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? - scenario.Location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope.Value; - double betaRequired = scenario.ModelFactors.RequiredProbabilityOfFailureStabilityInnerslope ?? - scenario.Location.ModelFactors.RequiredProbabilityOfFailureStabilityInnerslope.Value; - const int maxRedesignIterations = 200; - int iterationIndex = 1; - string previousFilename; - SurfaceLine2 orgSurfaceLine = scenario.Location.LocalXZSurfaceLine2; +// private void RedesignCombinedSlopeAdaptionAndShoulderAdaption(Scenario scenario, StabilityCalculator stabilityCalculator, +// SoilGeometryProbability soilProfileProbability) +// { +// Location location = scenario.Location; +// double requiredSafetyFactor = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? +// scenario.Location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope.Value; +// double betaRequired = scenario.ModelFactors.RequiredProbabilityOfFailureStabilityInnerslope ?? +// scenario.Location.ModelFactors.RequiredProbabilityOfFailureStabilityInnerslope.Value; +// const int maxRedesignIterations = 200; +// int iterationIndex = 1; +// string previousFilename; +// SurfaceLine2 orgSurfaceLine = scenario.Location.LocalXZSurfaceLine2; +// +// // Create the file with the initial geometry to be used to determine which layers have to be defined as dike embankment material +// CreateInitialGeometry(scenario, stabilityCalculator, soilProfileProbability, orgSurfaceLine, out previousFilename); +// SurfaceLine2 surfaceLine = scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName).FullDeepClone(); +// +// var mstabDesignEmbankment = new MStabDesignEmbankment +// { +// EmbankmentMaterialname = location.DikeEmbankmentMaterial, +// PreviousGeometry2DFilename = previousFilename +// }; +// +// try +// { +// double? beta; +// bool isRedesignRequired; +// double? exitPointXCoordinate; +// scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); +// stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, +// GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), +// iterationIndex, mstabDesignEmbankment); +// mstabDesignEmbankment.PreviousGeometry2DFilename = stabilityCalculator.StabilityProjectFilename; +// mstabDesignEmbankment.EmbankmentMaterialname = location.ShoulderEmbankmentMaterial; +// MStabResults? mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName); +// double? safetyFactor = mStabResults.Value.zone1.safetyFactor; +// beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName); +// isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); +// exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; +// +// if (!isRedesignRequired && surfaceLine != null) +// { +// // Set redesigned surfaceline to original, so in case no redesign is needed, the original surfaceline will be returned +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName, surfaceLine); +// } +// else +// { +// double maxFractionOfDikeHeightForShoulderHeight = scenario.Location.UseNewMaxHeightShoulderAsFraction ? +// scenario.Location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; +// double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, maxFractionOfDikeHeightForShoulderHeight); +// while (isRedesignRequired && surfaceLine != null) +// { +// iterationIndex++; +// if (iterationIndex >= maxRedesignIterations) +// { +// throw new MaximumRedesignIterationsReachedException(); +// } +// +// GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); +// if (exitPointXCoordinate > limitPointForShoulderDesign.X) +// { +// // If exit point of circle is after the limitPointForShoulderDesign then enlarge the shoulder +// +// // Determine new width and height for shoulder +// double shoulderHeight; +// double shoulderWidth; +// DetermineNewShoulderWidthAndHeight(scenario.Location.StabilityShoulderGrowDeltaX, +// scenario.Location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, out shoulderHeight, out shoulderWidth); +// +// // Create new shoulder +// var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, scenario.Location); +// surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; +// surfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); +// +// var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); +// if (validationError != null) +// { +// throw new SurfaceLineException(validationError.Text); +// } +// +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, surfaceLine); +// } +// else +// { +// // If exit point of circle is in the slope (inward) of the dike or the top of the shoulder then adapt slope +// var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, scenario.Location); +// surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLine(scenario.Location.StabilitySlopeAdaptionDeltaX); +// +// var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); +// if (validationError != null) +// { +// throw new SurfaceLineException(validationError.Text); +// } +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName, surfaceLine); +// } +// +// scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); +// stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, +// GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), +// iterationIndex, mstabDesignEmbankment); +// +// mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName); +// safetyFactor = mStabResults.Value.zone1.safetyFactor; +// beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName); +// isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); +// exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; +// } +// } +// scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, "Succes"); +// } +// catch (Exception exception) +// { +// string errorMessage = "FAIL: " + exception.Message; +// Exception innerException = exception.InnerException; +// while (innerException != null) +// { +// errorMessage = errorMessage + ";" + innerException.Message; +// innerException = innerException.InnerException; +// } +// scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, errorMessage); +// // Add message to log too for output tab. +// errorMessage = scenario.Location.Name + ", scenario " + scenario.LocationScenarioID + ", " + soilProfileProbability.SoilGeometryName + " " + errorMessage; +// stabilityCalculator.ErrorMessages.Add(new LogMessage(LogMessageType.Error, this, errorMessage)); +// scenario.CalculationResult = CalculationResult.RunFailed; +// // Redesign not succesful, so no redesigned surfaceline will be returned +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, null); +// } +// foreach (var errorMessage in stabilityCalculator.ErrorMessages) +// { +// errorMessages.Add(errorMessage); +// } +// } - // Create the file with the initial geometry to be used to determine which layers have to be defined as dike embankment material - CreateInitialGeometry(scenario, stabilityCalculator, soilProfileProbability, orgSurfaceLine, out previousFilename); - SurfaceLine2 surfaceLine = scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName).FullDeepClone(); - - var mstabDesignEmbankment = new MStabDesignEmbankment - { - EmbankmentMaterialname = location.DikeEmbankmentMaterial, - PreviousGeometry2DFilename = previousFilename - }; - - try - { - double? beta; - bool isRedesignRequired; - double? exitPointXCoordinate; - scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); - stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, - GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), - iterationIndex, mstabDesignEmbankment); - mstabDesignEmbankment.PreviousGeometry2DFilename = stabilityCalculator.StabilityProjectFilename; - mstabDesignEmbankment.EmbankmentMaterialname = location.ShoulderEmbankmentMaterial; - MStabResults? mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName); - double? safetyFactor = mStabResults.Value.zone1.safetyFactor; - beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName); - isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); - exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; - - if (!isRedesignRequired && surfaceLine != null) - { - // Set redesigned surfaceline to original, so in case no redesign is needed, the original surfaceline will be returned - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName, surfaceLine); - } - else - { - double maxFractionOfDikeHeightForShoulderHeight = scenario.Location.UseNewMaxHeightShoulderAsFraction ? - scenario.Location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; - double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, maxFractionOfDikeHeightForShoulderHeight); - while (isRedesignRequired && surfaceLine != null) - { - iterationIndex++; - if (iterationIndex >= maxRedesignIterations) - { - throw new MaximumRedesignIterationsReachedException(); - } - - GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); - if (exitPointXCoordinate > limitPointForShoulderDesign.X) - { - // If exit point of circle is after the limitPointForShoulderDesign then enlarge the shoulder - - // Determine new width and height for shoulder - double shoulderHeight; - double shoulderWidth; - DetermineNewShoulderWidthAndHeight(scenario.Location.StabilityShoulderGrowDeltaX, - scenario.Location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, out shoulderHeight, out shoulderWidth); - - // Create new shoulder - var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, scenario.Location); - surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; - surfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); - - var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); - if (validationError != null) - { - throw new SurfaceLineException(validationError.Text); - } - - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, surfaceLine); - } - else - { - // If exit point of circle is in the slope (inward) of the dike or the top of the shoulder then adapt slope - var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, scenario.Location); - surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLine(scenario.Location.StabilitySlopeAdaptionDeltaX); - - var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); - if (validationError != null) - { - throw new SurfaceLineException(validationError.Text); - } - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName, surfaceLine); - } - - scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); - stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, - GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), - iterationIndex, mstabDesignEmbankment); - - mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName); - safetyFactor = mStabResults.Value.zone1.safetyFactor; - beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName); - isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); - exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; - } - } - scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, "Succes"); - } - catch (Exception exception) - { - string errorMessage = "FAIL: " + exception.Message; - Exception innerException = exception.InnerException; - while (innerException != null) - { - errorMessage = errorMessage + ";" + innerException.Message; - innerException = innerException.InnerException; - } - scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, errorMessage); - // Add message to log too for output tab. - errorMessage = scenario.Location.Name + ", scenario " + scenario.LocationScenarioID + ", " + soilProfileProbability.SoilGeometryName + " " + errorMessage; - stabilityCalculator.ErrorMessages.Add(new LogMessage(LogMessageType.Error, this, errorMessage)); - scenario.CalculationResult = CalculationResult.RunFailed; - // Redesign not succesful, so no redesigned surfaceline will be returned - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, null); - } - foreach (var errorMessage in stabilityCalculator.ErrorMessages) - { - errorMessages.Add(errorMessage); - } - } - /// /// Determines the new height and width of the shoulder width /// @@ -1700,21 +1706,21 @@ /// The limit point for shoulder design. /// New height of the shoulder. /// New width of the shoulder. - private static void DetermineNewShoulderWidthAndHeight(double shoulderGrowDeltaX, double shoulderGrowSlope, - SurfaceLine2 surfaceLine, GeometryPoint limitPointForShoulderDesign, out double shoulderHeight, out double shoulderWidth) - { - // Determine new shoulderpoint - var newShoulderPoint = new GeometryPoint() - { - X = limitPointForShoulderDesign.X + shoulderGrowDeltaX, - Z = limitPointForShoulderDesign.Z + shoulderGrowDeltaX*shoulderGrowSlope - }; +// private static void DetermineNewShoulderWidthAndHeight(double shoulderGrowDeltaX, double shoulderGrowSlope, +// SurfaceLine2 surfaceLine, GeometryPoint limitPointForShoulderDesign, out double shoulderHeight, out double shoulderWidth) +// { +// // Determine new shoulderpoint +// var newShoulderPoint = new GeometryPoint() +// { +// X = limitPointForShoulderDesign.X + shoulderGrowDeltaX, +// Z = limitPointForShoulderDesign.Z + shoulderGrowDeltaX*shoulderGrowSlope +// }; +// +// // Determine new shoulder width and height +// shoulderWidth = surfaceLine.DetermineShoulderLengthForGivenShoulderTopInside(newShoulderPoint); +// shoulderHeight = newShoulderPoint.Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; +// } - // Determine new shoulder width and height - shoulderWidth = surfaceLine.DetermineShoulderLengthForGivenShoulderTopInside(newShoulderPoint); - shoulderHeight = newShoulderPoint.Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; - } - /// /// Redesign for Stability: /// - first do slope adaption (until required safety is reached) @@ -1727,177 +1733,177 @@ /// /// /// - private void RedesignFirstSlopeAdaptionThenShoulderAdaption(Scenario scenario, StabilityCalculator stabilityCalculator, - SoilGeometryProbability soilProfileProbability) - { - Location location = scenario.Location; - double requiredSafetyFactor = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? - scenario.Location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope.Value; - double betaRequired = scenario.ModelFactors.RequiredProbabilityOfFailureStabilityInnerslope ?? - scenario.Location.ModelFactors.RequiredProbabilityOfFailureStabilityInnerslope.Value; - const int maxRedesignIterations = 200; - int iterationIndex = 1; - string previousFilename; - SurfaceLine2 orgSurfaceLine = scenario.Location.LocalXZSurfaceLine2; +// private void RedesignFirstSlopeAdaptionThenShoulderAdaption(Scenario scenario, StabilityCalculator stabilityCalculator, +// SoilGeometryProbability soilProfileProbability) +// { +// Location location = scenario.Location; +// double requiredSafetyFactor = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? +// scenario.Location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope.Value; +// double betaRequired = scenario.ModelFactors.RequiredProbabilityOfFailureStabilityInnerslope ?? +// scenario.Location.ModelFactors.RequiredProbabilityOfFailureStabilityInnerslope.Value; +// const int maxRedesignIterations = 200; +// int iterationIndex = 1; +// string previousFilename; +// SurfaceLine2 orgSurfaceLine = scenario.Location.LocalXZSurfaceLine2; +// +// // Create the file with the initial geometry to be used to determine which layers have to be defined as dike embankment material +// CreateInitialGeometry(scenario, stabilityCalculator, soilProfileProbability, orgSurfaceLine, out previousFilename); +// SurfaceLine2 surfaceLine = scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName).FullDeepClone(); +// +// var mstabDesignEmbankment = new MStabDesignEmbankment +// { +// EmbankmentMaterialname = location.DikeEmbankmentMaterial, +// PreviousGeometry2DFilename = previousFilename +// }; +// +// try +// { +// double? beta; +// bool isRedesignRequired; +// double? exitPointXCoordinate; +// scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); +// stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, +// GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), +// iterationIndex, mstabDesignEmbankment); +// mstabDesignEmbankment.PreviousGeometry2DFilename = stabilityCalculator.StabilityProjectFilename; +// mstabDesignEmbankment.EmbankmentMaterialname = location.ShoulderEmbankmentMaterial; +// MStabResults? mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName); +// double? safetyFactor = mStabResults.Value.zone1.safetyFactor; +// beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName); +// isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); +// exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; +// +// if (!isRedesignRequired && surfaceLine != null) +// { +// // Set redesigned surfaceline to original, so in case no redesign is needed, the original surfaceline will be returned +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName, surfaceLine); +// } +// else +// { +// double maxFractionOfDikeHeightForShoulderHeight = scenario.Location.UseNewMaxHeightShoulderAsFraction ? +// scenario.Location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; +// double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, maxFractionOfDikeHeightForShoulderHeight); +// while (isRedesignRequired && surfaceLine != null) +// { +// // First slope adaption +// double startCoTangent = location.SlopeAdaptionStartCotangent; +// double endCoTangent = location.SlopeAdaptionEndCotangent; +// double stepCoTangent = location.SlopeAdaptionStepCotangent; +// var orgCotangent = surfaceLine.GetCotangentOfInnerSlope(); +// double coTangent = startCoTangent; +// double currentCoTangent = orgCotangent; +// +// // Find out for which cotangent we want to start designing +// while (coTangent <= orgCotangent) +// { +// coTangent += stepCoTangent; +// } +// +// // Design for slope adaption +// GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); +// while (isRedesignRequired && (coTangent < endCoTangent)) +// { +// iterationIndex++; +// if (iterationIndex >= maxRedesignIterations) +// { +// throw new MaximumRedesignIterationsReachedException(); +// } +// var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, scenario.Location); +// // The parameter for ConstructNewSurfaceLineBySlope is the tangent of the slope, so use reciproce value +// surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLineBySlope(1/coTangent); +// currentCoTangent = coTangent; +// +// var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); +// if (validationError != null) +// { +// throw new SurfaceLineException(validationError.Text); +// } +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName, surfaceLine); +// +// // Recalculate new surfaceline +// scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); +// stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, +// GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), +// iterationIndex, mstabDesignEmbankment); +// mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName); +// safetyFactor = mStabResults.Value.zone1.safetyFactor; +// exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; +// beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, +// soilProfileProbability.SoilGeometry2DName); +// isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); +// limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); +// +// coTangent += stepCoTangent; +// } +// +// // Then shoulder adaption +// while (isRedesignRequired && surfaceLine != null) +// { +// iterationIndex++; +// if (iterationIndex >= maxRedesignIterations) +// { +// throw new MaximumRedesignIterationsReachedException(); +// } +// +// // Determine new width and height for shoulder +// double shoulderHeight; +// double shoulderWidth; +// DetermineNewShoulderWidthAndHeight(scenario.Location.StabilityShoulderGrowDeltaX, +// scenario.Location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, out shoulderHeight, out shoulderWidth); +// +// // Create new shoulder +// var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, scenario.Location); +// surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; +// surfaceLineShoulderAdapter.SlopeOfNewShoulder = currentCoTangent; +// surfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); +// +// var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); +// if (validationError != null) +// { +// throw new SurfaceLineException(validationError.Text); +// } +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, surfaceLine); +// +// // Recalculate new surfaceline +// scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); +// stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, +// GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), +// iterationIndex, mstabDesignEmbankment); +// mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); +// safetyFactor = mStabResults.Value.zone1.safetyFactor; +// beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); +// isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); +// limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); +// } +// } +// } +// scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, "Succes"); +// } +// catch (Exception exception) +// { +// string errorMessage = "FAIL: " + exception.Message; +// Exception innerException = exception.InnerException; +// while (innerException != null) +// { +// errorMessage = errorMessage + ";" + innerException.Message; +// innerException = innerException.InnerException; +// } +// scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, errorMessage); +// scenario.CalculationResult = CalculationResult.RunFailed; +// // Redesign not succesful, so no redesigned surfaceline will be returned +// scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, null); +// } +// foreach (var errorMessage in stabilityCalculator.ErrorMessages) +// { +// errorMessages.Add(errorMessage); +// } +// } - // Create the file with the initial geometry to be used to determine which layers have to be defined as dike embankment material - CreateInitialGeometry(scenario, stabilityCalculator, soilProfileProbability, orgSurfaceLine, out previousFilename); - SurfaceLine2 surfaceLine = scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName).FullDeepClone(); - - var mstabDesignEmbankment = new MStabDesignEmbankment - { - EmbankmentMaterialname = location.DikeEmbankmentMaterial, - PreviousGeometry2DFilename = previousFilename - }; - - try - { - double? beta; - bool isRedesignRequired; - double? exitPointXCoordinate; - scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); - stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, - GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), - iterationIndex, mstabDesignEmbankment); - mstabDesignEmbankment.PreviousGeometry2DFilename = stabilityCalculator.StabilityProjectFilename; - mstabDesignEmbankment.EmbankmentMaterialname = location.ShoulderEmbankmentMaterial; - MStabResults? mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName); - double? safetyFactor = mStabResults.Value.zone1.safetyFactor; - beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName); - isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); - exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; - - if (!isRedesignRequired && surfaceLine != null) - { - // Set redesigned surfaceline to original, so in case no redesign is needed, the original surfaceline will be returned - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName, surfaceLine); - } - else - { - double maxFractionOfDikeHeightForShoulderHeight = scenario.Location.UseNewMaxHeightShoulderAsFraction ? - scenario.Location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; - double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, maxFractionOfDikeHeightForShoulderHeight); - while (isRedesignRequired && surfaceLine != null) - { - // First slope adaption - double startCoTangent = location.SlopeAdaptionStartCotangent; - double endCoTangent = location.SlopeAdaptionEndCotangent; - double stepCoTangent = location.SlopeAdaptionStepCotangent; - var orgCotangent = surfaceLine.GetCotangentOfInnerSlope(); - double coTangent = startCoTangent; - double currentCoTangent = orgCotangent; - - // Find out for which cotangent we want to start designing - while (coTangent <= orgCotangent) - { - coTangent += stepCoTangent; - } - - // Design for slope adaption - GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); - while (isRedesignRequired && (coTangent < endCoTangent)) - { - iterationIndex++; - if (iterationIndex >= maxRedesignIterations) - { - throw new MaximumRedesignIterationsReachedException(); - } - var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, scenario.Location); - // The parameter for ConstructNewSurfaceLineBySlope is the tangent of the slope, so use reciproce value - surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLineBySlope(1/coTangent); - currentCoTangent = coTangent; - - var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); - if (validationError != null) - { - throw new SurfaceLineException(validationError.Text); - } - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName, surfaceLine); - - // Recalculate new surfaceline - scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); - stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, - GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), - iterationIndex, mstabDesignEmbankment); - mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName); - safetyFactor = mStabResults.Value.zone1.safetyFactor; - exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; - beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, - soilProfileProbability.SoilGeometry2DName); - isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); - limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); - - coTangent += stepCoTangent; - } - - // Then shoulder adaption - while (isRedesignRequired && surfaceLine != null) - { - iterationIndex++; - if (iterationIndex >= maxRedesignIterations) - { - throw new MaximumRedesignIterationsReachedException(); - } - - // Determine new width and height for shoulder - double shoulderHeight; - double shoulderWidth; - DetermineNewShoulderWidthAndHeight(scenario.Location.StabilityShoulderGrowDeltaX, - scenario.Location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, out shoulderHeight, out shoulderWidth); - - // Create new shoulder - var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, scenario.Location); - surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; - surfaceLineShoulderAdapter.SlopeOfNewShoulder = currentCoTangent; - surfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); - - var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); - if (validationError != null) - { - throw new SurfaceLineException(validationError.Text); - } - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, surfaceLine); - - // Recalculate new surfaceline - scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); - stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile, - GetFullSoilGeometry2DName(soilProfileProbability.SoilGeometry2DName), - iterationIndex, mstabDesignEmbankment); - mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); - safetyFactor = mStabResults.Value.zone1.safetyFactor; - beta = scenario.GetFailureProbabilityStability(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName); - isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor, betaRequired, beta); - limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); - } - } - } - scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, "Succes"); - } - catch (Exception exception) - { - string errorMessage = "FAIL: " + exception.Message; - Exception innerException = exception.InnerException; - while (innerException != null) - { - errorMessage = errorMessage + ";" + innerException.Message; - innerException = innerException.InnerException; - } - scenario.SetResultMessage(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, errorMessage); - scenario.CalculationResult = CalculationResult.RunFailed; - // Redesign not succesful, so no redesigned surfaceline will be returned - scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, null); - } - foreach (var errorMessage in stabilityCalculator.ErrorMessages) - { - errorMessages.Add(errorMessage); - } - } - /// /// Redesigns the surface line flow slide. /// @@ -1936,51 +1942,51 @@ /// /// /// - private PipingCalculator pipingCalculatorFactory(Location location, ModelParametersForPLLines modelParametersForPLLines, PipingModelType pipingModelType, double upliftCriterion, double requiredSafetyFactorPiping, PipingProbabilisticParameters? pipingProbabilisticParameters) - { - switch (pipingModelType) - { - case PipingModelType.Bligh: - return new PipingCalculatorBligh(modelParametersForPLLines, - requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); - case PipingModelType.Sellmeijer: - PipingProbabilisticParameters? actualPipingProbabilisticParameters = null; - if ((ProbabilisticType == ProbabilisticType.Probabilistic) || (ProbabilisticType == ProbabilisticType.ProbabilisticFragility)) - { - actualPipingProbabilisticParameters = pipingProbabilisticParameters; - } - return new PipingCalculatorSellmeijer(modelParametersForPLLines, - requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, actualPipingProbabilisticParameters, upliftCriterion); - case PipingModelType.Sellmeijer2Forces: - return new PipingCalculatorSellmeijer2Forces(modelParametersForPLLines, - requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); - case PipingModelType.Sellmeijer4Forces: - return new PipingCalculatorSellmeijer4Forces(modelParametersForPLLines, - requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); - case PipingModelType.Wti2017: - return new PipingCalculatorWti2017(modelParametersForPLLines, - requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); - } - return null; - } +// private PipingCalculator pipingCalculatorFactory(Location location, ModelParametersForPLLines modelParametersForPLLines, PipingModelType pipingModelType, double upliftCriterion, double requiredSafetyFactorPiping, PipingProbabilisticParameters? pipingProbabilisticParameters) +// { +// switch (pipingModelType) +// { +// case PipingModelType.Bligh: +// return new PipingCalculatorBligh(modelParametersForPLLines, +// requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); +// case PipingModelType.Sellmeijer: +// PipingProbabilisticParameters? actualPipingProbabilisticParameters = null; +// if ((ProbabilisticType == ProbabilisticType.Probabilistic) || (ProbabilisticType == ProbabilisticType.ProbabilisticFragility)) +// { +// actualPipingProbabilisticParameters = pipingProbabilisticParameters; +// } +// return new PipingCalculatorSellmeijer(modelParametersForPLLines, +// requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, actualPipingProbabilisticParameters, upliftCriterion); +// case PipingModelType.Sellmeijer2Forces: +// return new PipingCalculatorSellmeijer2Forces(modelParametersForPLLines, +// requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); +// case PipingModelType.Sellmeijer4Forces: +// return new PipingCalculatorSellmeijer4Forces(modelParametersForPLLines, +// requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); +// case PipingModelType.Wti2017: +// return new PipingCalculatorWti2017(modelParametersForPLLines, +// requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); +// } +// return null; +// } /// /// /// /// /// - private string GetFullSoilGeometry2DName(string soilGeometry2DName) - { - if (soilGeometry2DName == null) - { - return null; - } - else - { - string fullSoilGeometry2DName = Path.Combine(DamProject.ProjectMap, Path.Combine(MapForSoilGeometries2D, soilGeometry2DName)); - return fullSoilGeometry2DName; - } - } +// private string GetFullSoilGeometry2DName(string soilGeometry2DName) +// { +// if (soilGeometry2DName == null) +// { +// return null; +// } +// else +// { +// string fullSoilGeometry2DName = Path.Combine(DamProjectData.ProjectMap, Path.Combine(MapForSoilGeometries2D, soilGeometry2DName)); +// return fullSoilGeometry2DName; +// } +// } /// /// Get the directory where to create the piping project files Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamFailureMechanismeCalculationSpecification.cs =================================================================== diff -u -r316 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamFailureMechanismeCalculationSpecification.cs (.../DamFailureMechanismeCalculationSpecification.cs) (revision 316) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamFailureMechanismeCalculationSpecification.cs (.../DamFailureMechanismeCalculationSpecification.cs) (revision 330) @@ -207,27 +207,27 @@ /// public void ReadUserSettingsSlipCircleDefinition() { - if (failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition == null) - { - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition = new SlipCircleDefinition(); - } - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanTangentLinesDefinition = Properties.Settings.Default.SlipCircleUpliftVanTangentLinesDefinition; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanTangentLinesDistance = Properties.Settings.Default.SlipCircleUpliftVanTangentLinesDistance; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopTangentLinesDefinition = Properties.Settings.Default.SlipCircleBishopTangentLinesDefinition; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopTangentLinesDistance = Properties.Settings.Default.SlipCircleBishopTangentLinesDistance; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.GridSizeDetermination = Properties.Settings.Default.SlipCircleGridSizeDetermination; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanLeftGridVerticalPointCount = Properties.Settings.Default.SlipCircleUpliftVanLeftGridVerticalPointCount; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanLeftGridVerticalPointDistance = Properties.Settings.Default.SlipCircleUpliftVanLeftGridVerticalPointDistance; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanLeftGridHorizontalPointCount = Properties.Settings.Default.SlipCircleUpliftVanLeftGridHorizontalPointCount; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanLeftGridHorizontalPointDistance = Properties.Settings.Default.SlipCircleUpliftVanLeftGridHorizontalPointDistance; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanRightGridVerticalPointCount = Properties.Settings.Default.SlipCircleUpliftVanRightGridVerticalPointCount; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanRightGridVerticalPointDistance = Properties.Settings.Default.SlipCircleUpliftVanRightGridVerticalPointDistance; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanRightGridHorizontalPointCount = Properties.Settings.Default.SlipCircleUpliftVanRightGridHorizontalPointCount; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanRightGridHorizontalPointDistance = Properties.Settings.Default.SlipCircleUpliftVanRightGridHorizontalPointDistance; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopGridVerticalPointCount = Properties.Settings.Default.SlipCircleBishopGridVerticalPointCount; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopGridVerticalPointDistance = Properties.Settings.Default.SlipCircleBishopGridVerticalPointDistance; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopGridHorizontalPointCount = Properties.Settings.Default.SlipCircleBishopGridHorizontalPointCount; - failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopGridHorizontalPointDistance = Properties.Settings.Default.SlipCircleBishopGridHorizontalPointDistance; +// if (failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition == null) +// { +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition = new SlipCircleDefinition(); +// } +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanTangentLinesDefinition = Properties.Settings.Default.SlipCircleUpliftVanTangentLinesDefinition; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanTangentLinesDistance = Properties.Settings.Default.SlipCircleUpliftVanTangentLinesDistance; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopTangentLinesDefinition = Properties.Settings.Default.SlipCircleBishopTangentLinesDefinition; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopTangentLinesDistance = Properties.Settings.Default.SlipCircleBishopTangentLinesDistance; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.GridSizeDetermination = Properties.Settings.Default.SlipCircleGridSizeDetermination; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanLeftGridVerticalPointCount = Properties.Settings.Default.SlipCircleUpliftVanLeftGridVerticalPointCount; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanLeftGridVerticalPointDistance = Properties.Settings.Default.SlipCircleUpliftVanLeftGridVerticalPointDistance; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanLeftGridHorizontalPointCount = Properties.Settings.Default.SlipCircleUpliftVanLeftGridHorizontalPointCount; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanLeftGridHorizontalPointDistance = Properties.Settings.Default.SlipCircleUpliftVanLeftGridHorizontalPointDistance; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanRightGridVerticalPointCount = Properties.Settings.Default.SlipCircleUpliftVanRightGridVerticalPointCount; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanRightGridVerticalPointDistance = Properties.Settings.Default.SlipCircleUpliftVanRightGridVerticalPointDistance; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanRightGridHorizontalPointCount = Properties.Settings.Default.SlipCircleUpliftVanRightGridHorizontalPointCount; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanRightGridHorizontalPointDistance = Properties.Settings.Default.SlipCircleUpliftVanRightGridHorizontalPointDistance; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopGridVerticalPointCount = Properties.Settings.Default.SlipCircleBishopGridVerticalPointCount; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopGridVerticalPointDistance = Properties.Settings.Default.SlipCircleBishopGridVerticalPointDistance; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopGridHorizontalPointCount = Properties.Settings.Default.SlipCircleBishopGridHorizontalPointCount; +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.BishopGridHorizontalPointDistance = Properties.Settings.Default.SlipCircleBishopGridHorizontalPointDistance; } } } Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/HydraulicShortcutRWEvaluator.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/HydraulicShortcutRWEvaluator.cs (.../HydraulicShortcutRWEvaluator.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/HydraulicShortcutRWEvaluator.cs (.../HydraulicShortcutRWEvaluator.cs) (revision 330) @@ -138,7 +138,7 @@ { double? upliftFactor = 0.0; - upliftFactor = GetLowestUpliftFactor(); + // upliftFactor = GetLowestUpliftFactor(); ## Bka if (upliftFactor != null) { isDrySensitive = (upliftFactor.Value < cMinUpliftFactor); @@ -227,59 +227,59 @@ /// Create PL-lines /// /// - private PLLines CreatePLLines() - { - PLLinesCreator plLinesCreator = new PLLinesCreator(); - plLinesCreator.WaterLevelRiverHigh = GetBoezemLevel(); - plLinesCreator.HeadInPLLine2 = location.HeadPL2; - plLinesCreator.HeadInPLLine3 = location.HeadPl3; - plLinesCreator.HeadInPLLine4 = location.HeadPl4; +// private PLLines CreatePLLines() +// { +// PLLinesCreator plLinesCreator = new PLLinesCreator(); +// plLinesCreator.WaterLevelRiverHigh = GetBoezemLevel(); +// plLinesCreator.HeadInPLLine2 = location.HeadPL2; +// plLinesCreator.HeadInPLLine3 = location.HeadPl3; +// plLinesCreator.HeadInPLLine4 = location.HeadPl4; +// +// plLinesCreator.SurfaceLine = location.LocalXZSurfaceLine2; +// plLinesCreator.WaterLevelPolder = location.PolderLevel; +// plLinesCreator.ModelParametersForPLLines = location.CreateModelParametersForPLLines(); +// plLinesCreator.SoilProfile = soilGeometry.SoilProfile; +// plLinesCreator.SoilGeometry2DName = null; +// plLinesCreator.SoilGeometryType = SoilGeometryType.SoilGeometry1D; +// plLinesCreator.GaugePLLines = null; +// plLinesCreator.Gauges = null; +// plLinesCreator.GaugeMissVal = 0.0; +// plLinesCreator.IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true; // for stability this must set to true +// plLinesCreator.PlLineOffsetBelowDikeTopAtRiver = location.PlLineOffsetBelowDikeTopAtRiver; +// plLinesCreator.PlLineOffsetBelowDikeTopAtPolder = location.PlLineOffsetBelowDikeTopAtPolder; +// plLinesCreator.SoilBaseDB = null; // soilbase; +// plLinesCreator.DikeEmbankmentMaterial = null; // soilbase.GetSoil(location.DikeEmbankmentMaterial); +// plLinesCreator.IsUseOvenDryUnitWeight = (dikeDrySensitivity == DikeDrySensitivity.Dry); +// plLinesCreator.IsHydraulicShortcut = false; // in this evaluation obviously no hydraulic shortcut +// plLinesCreator.XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin; +// +// PLLines plLines = plLinesCreator.CreateAllPLLines(location); +// return plLines; +// } - plLinesCreator.SurfaceLine = location.LocalXZSurfaceLine2; - plLinesCreator.WaterLevelPolder = location.PolderLevel; - plLinesCreator.ModelParametersForPLLines = location.CreateModelParametersForPLLines(); - plLinesCreator.SoilProfile = soilGeometry.SoilProfile; - plLinesCreator.SoilGeometry2DName = null; - plLinesCreator.SoilGeometryType = SoilGeometryType.SoilGeometry1D; - plLinesCreator.GaugePLLines = null; - plLinesCreator.Gauges = null; - plLinesCreator.GaugeMissVal = 0.0; - plLinesCreator.IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true; // for stability this must set to true - plLinesCreator.PlLineOffsetBelowDikeTopAtRiver = location.PlLineOffsetBelowDikeTopAtRiver; - plLinesCreator.PlLineOffsetBelowDikeTopAtPolder = location.PlLineOffsetBelowDikeTopAtPolder; - plLinesCreator.SoilBaseDB = null; // soilbase; - plLinesCreator.DikeEmbankmentMaterial = null; // soilbase.GetSoil(location.DikeEmbankmentMaterial); - plLinesCreator.IsUseOvenDryUnitWeight = (dikeDrySensitivity == DikeDrySensitivity.Dry); - plLinesCreator.IsHydraulicShortcut = false; // in this evaluation obviously no hydraulic shortcut - plLinesCreator.XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin; - - PLLines plLines = plLinesCreator.CreateAllPLLines(location); - return plLines; - } - /// /// Determine where lowest uplift factor occurs and the value of that factor /// /// - private double? GetLowestUpliftFactor() - { - - UpliftLocationDeterminator upliftLocationDeterminator = new UpliftLocationDeterminator() - { - SurfaceLine = location.SurfaceLine2, - SoilProfile = soilGeometry.SoilProfile, - SoilGeometry2DName = null, - SoilBaseDB = null, //soilbase, - DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), - PLLines = CreatePLLines(), - IsUseOvenDryUnitWeight = (dikeDrySensitivity == DikeDrySensitivity.Dry), - XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin - }; - UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationAtWithLowestUpliftFactor(); - if (upliftLocationAndResult != null) - return upliftLocationAndResult.UpliftFactor; - else - return null; - } +// private double? GetLowestUpliftFactor() +// { +// +// UpliftLocationDeterminator upliftLocationDeterminator = new UpliftLocationDeterminator() +// { +// SurfaceLine = location.SurfaceLine2, +// SoilProfile = soilGeometry.SoilProfile, +// SoilGeometry2DName = null, +// SoilBaseDB = null, //soilbase, +// DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), +// PLLines = CreatePLLines(), +// IsUseOvenDryUnitWeight = (dikeDrySensitivity == DikeDrySensitivity.Dry), +// XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin +// }; +// UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationAtWithLowestUpliftFactor(); +// if (upliftLocationAndResult != null) +// return upliftLocationAndResult.UpliftFactor; +// else +// return null; +// } } } \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ObjectExtensions.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ObjectExtensions.cs (.../ObjectExtensions.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ObjectExtensions.cs (.../ObjectExtensions.cs) (revision 330) @@ -22,6 +22,8 @@ using System; using System.Collections; using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; using System.Linq; using System.Reflection; @@ -32,6 +34,7 @@ /// public static class ObjectExtensions { + public static readonly CultureInfo DefaultCulture = new CultureInfo("nl-NL"); private const double threshold = 0.0000001; /// @@ -67,6 +70,167 @@ return (Math.Abs(double1 - double2) <= precision); } + /// + /// Converts an object to another type. Also works with nullable types. The method can't. + /// + /// + /// Also works with nullable types and enums. The method can't do this. + /// + /// The type to converto to + /// The object to convert + /// The converted object + /// When is null and name="type"/> is value type and not nullable. + /// When an error occurs during conversion. + public static T ToType(this object value) + { + if (value == null) + { + ThrowIfValueType(); + + return default(T); + } + + return (T)value.ToType(typeof(T), DefaultCulture); + } + + /// + /// Converts an object to another type. + /// + /// + /// Also works with nullable types and enums. The method can't do this. + /// This method can also be used to downcast numeric values for example from string (double) value "12,0" to short 12 + /// When trying to convert a string to double and the dutch culture is set, then this method tries to + /// parse the string with custom logic. Because it occures that some string are not properly + /// changed according to the current culture. For instance in dbf files where numeric values are stored as + /// strings (for example "10,23") + /// Use this method with care when high performance is required it is not yet tested with large data sets + /// + /// The value to convert + /// The target type to convert to + /// + /// The converted type + /// When is null and is value type and not nullable. + /// When an error occurs during conversion. + public static object ToType(this object value, Type type, CultureInfo culture) + { + if (value == null) + { + ThrowIfValueType(type); + + return null; + } + + if (type.IsEnum) + { + return value.ToEnumType(type); + } + + object result = null; + + if (IsNullable(type)) + { + try + { + var nullableConverter = new NullableConverter(type); + type = nullableConverter.UnderlyingType; + result = Convert.ChangeType(value, type, CultureInfo.InvariantCulture); + } + catch + { + result = null; + } + } + else + { + try + { + if (type == typeof(double) && value is string) + { + if (Equals(culture, new CultureInfo("nl-NL"))) + { + // TODO: Needs to be tested !! + // TODO: replace parsing with regular expression + // TODO: to make this more flexible make parser injectable through lambda's + + var tmp = value as string; + if (tmp.Contains(",") && !tmp.Contains(".")) // 1,5 -> 1.5 + { + value = tmp.Replace(",", "."); + } + else if (tmp.Contains(",") && tmp.Contains(".") && tmp.Length > 4 && !tmp.Contains(" ")) + { + // 100,000.00 -> 100000.00 + value = tmp.Replace(",", ""); + } + + //TODO: how to handle 100,000 english notation? Seems not to occur in most/mabye all situations + } + result = value.Equals("NaN") ? Double.NaN : Convert.ChangeType(value, type, CultureInfo.InvariantCulture); + } + else + { + // value needs to be downcasted + + switch (type.Name) + { + case "SByte": + case "Byte": + case "Int16": + case "UInt16": + case "Int32": + case "UInt32": + case "Int64": + case "UInt64": + var tmp = Convert.ChangeType(value, typeof(double), CultureInfo.InvariantCulture); + result = Convert.ChangeType(tmp, type); + break; + default: + result = Convert.ChangeType(value, type, CultureInfo.InvariantCulture); + break; + } + } + } + catch (Exception e) + { + ThrowConversionException(value, type, e); + } + } + + return result; + } + + /// + /// Convert the value to the enum type + /// + /// The value to convert. + /// The type to convert to. + /// Ignores the case if set to true + /// The enum + public static object ToEnumType(this object value, Type type, bool ignoreCase = false) + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + if (!ignoreCase && !Enum.IsDefined(type, value)) + { + ThrowConversionException(value, type, null); + } + + string stringVal = value.ToString(); + object result = null; + try + { + result = Enum.Parse(type, stringVal, ignoreCase); + } + catch (Exception e) + { + ThrowConversionException(value, type, e); + } + return result; + } + /// /// Clone properties from an original object to a destination object. /// @@ -135,5 +299,56 @@ return typeof(IList).IsAssignableFrom(destinationProperty.PropertyType); } + /// + /// Throws an ArgumentNullException if target type to convert to is a ValueType. + /// + /// + private static void ThrowIfValueType() + { + ThrowIfValueType(typeof(T)); + } + + /// + /// Throws an ArgumentNullException if target type to convert to is a ValueType. + /// + /// The type. + private static void ThrowIfValueType(Type type) + { + if (type.IsValueType && !IsNullable(type)) + { + throw new ArgumentNullException( + string.Format("The value can't be null because parameter type {0} is a value type", type)); + } + } + + /// + /// Determines whether the specified type is nullable. + /// + /// The type. + /// + /// true if the specified type is nullable; otherwise, false. + /// + private static bool IsNullable(Type type) + { + return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + /// + /// Throws conversion exception. + /// + /// The value. + /// The type. + /// The exception. + private static void ThrowConversionException(object value, Type type, Exception e) + { + string v = ""; + try + { + v = value.ToString().Replace("\0", " "); + } + catch { } + + throw new ConversionException(type, v, e); + } } } \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamProjectCalculator.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamProjectCalculator.cs (.../DamProjectCalculator.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamProjectCalculator.cs (.../DamProjectCalculator.cs) (revision 330) @@ -27,12 +27,19 @@ using System.Linq; using System.Threading.Tasks; using System.Xml.Serialization; +using Deltares.DamEngine.Calculators.Uplift; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.PlLines; +using Deltares.DamEngine.Data.General.TimeSeries; using Deltares.DamEngine.Data.Geometry; +using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Logging; +using Deltares.DamEngine.Calculators.General; +using Deltares.DamEngine.Calculators.PlLinesCreator; +using Deltares.DamEngine.Calculators.Stability; +using Parallel = Deltares.DamEngine.Calculators.General.Parallel; namespace Deltares.DamEngine.Calculators { @@ -186,7 +193,7 @@ SurfaceLine = surfaceLine, SoilProfile = soilProfile, SoilGeometry2DName = soilGeometry2DName, - SoilBaseDB = location.SoilbaseDB, + //SoilBaseDB = location.SoilbaseDB, SoilList = location.SoilList, DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), PLLines = plLines, @@ -222,122 +229,120 @@ var scenario = (Scenario) scenarioTask; var scenarioName = scenario.Location.Name; Debug.WriteLine(String.Format("Start thread for location '{0}'", scenarioName)); - DataEventPublisher.InvokeWithoutPublishingEvents(() => + + Location oldLocation = null; + + try { - Location oldLocation = null; + oldLocation = scenario.Location; + var scenarioId = scenario.LocationScenarioID; + Debug.WriteLine("Location '{0}', scenario '{1}'", scenarioName, scenarioId); + scenario.ClearResults(); + scenario.ClearErrors(); - try + CloneLocationOnScenario(scenario); + + if (scenario.PlLineOffsetBelowDikeToeAtPolder.HasValue) { - oldLocation = scenario.Location; - var scenarioId = scenario.LocationScenarioID; - Debug.WriteLine("Location '{0}', scenario '{1}'", scenarioName, scenarioId); - scenario.ClearResults(); - scenario.ClearErrors(); + scenario.Location.PlLineOffsetBelowDikeToeAtPolder = scenario.PlLineOffsetBelowDikeToeAtPolder.Value; + } + if (scenario.PlLineOffsetBelowDikeTopAtPolder.HasValue) + { + scenario.Location.PlLineOffsetBelowDikeTopAtPolder = scenario.PlLineOffsetBelowDikeTopAtPolder.Value; + } + if (scenario.PlLineOffsetBelowDikeTopAtRiver.HasValue) + { + scenario.Location.PlLineOffsetBelowDikeTopAtRiver = scenario.PlLineOffsetBelowDikeTopAtRiver.Value; + } + if (scenario.PlLineOffsetBelowShoulderBaseInside.HasValue) + { + scenario.Location.PlLineOffsetBelowShoulderBaseInside = scenario.PlLineOffsetBelowShoulderBaseInside.Value; + } + if (scenario.PlLineOffsetBelowDikeCrestMiddle.HasValue) + { + scenario.Location.PlLineOffsetBelowDikeCrestMiddle = scenario.PlLineOffsetBelowDikeCrestMiddle; + } + if (scenario.PlLineOffsetFactorBelowShoulderCrest.HasValue) + { + scenario.Location.PlLineOffsetFactorBelowShoulderCrest = scenario.PlLineOffsetFactorBelowShoulderCrest; + } + if (scenario.UsePlLineOffsetBelowDikeCrestMiddle.HasValue) + { + scenario.Location.UsePlLineOffsetBelowDikeCrestMiddle = scenario.UsePlLineOffsetBelowDikeCrestMiddle; + } + if (scenario.UsePlLineOffsetFactorBelowShoulderCrest.HasValue) + { + scenario.Location.UsePlLineOffsetFactorBelowShoulderCrest = scenario.UsePlLineOffsetFactorBelowShoulderCrest; + } + if (scenario.HeadPl3.HasValue) + { + scenario.Location.HeadPl3 = scenario.HeadPl3.Value; + } + if (scenario.HeadPl4.HasValue) + { + scenario.Location.HeadPl4 = scenario.HeadPl4.Value; + } - CloneLocationOnScenario(scenario); + var selectedKernelType = StabilityKernelType.DamClassic; + var damProjectCalculationSpecification = damProjectData.DamProjectCalculationSpecification; + var spec = damProjectCalculationSpecification.DamCalculationSpecifications.First(); + if (spec != null) + { + selectedKernelType = spec.StabilityKernelType; + } + if (DetermineStabilityUpliftForScenarios(scenario, selectedKernelType)) + { - if (scenario.PlLineOffsetBelowDikeToeAtPolder.HasValue) - { - scenario.Location.PlLineOffsetBelowDikeToeAtPolder = scenario.PlLineOffsetBelowDikeToeAtPolder.Value; - } - if (scenario.PlLineOffsetBelowDikeTopAtPolder.HasValue) - { - scenario.Location.PlLineOffsetBelowDikeTopAtPolder = scenario.PlLineOffsetBelowDikeTopAtPolder.Value; - } - if (scenario.PlLineOffsetBelowDikeTopAtRiver.HasValue) - { - scenario.Location.PlLineOffsetBelowDikeTopAtRiver = scenario.PlLineOffsetBelowDikeTopAtRiver.Value; - } - if (scenario.PlLineOffsetBelowShoulderBaseInside.HasValue) - { - scenario.Location.PlLineOffsetBelowShoulderBaseInside = scenario.PlLineOffsetBelowShoulderBaseInside.Value; - } - if (scenario.PlLineOffsetBelowDikeCrestMiddle.HasValue) - { - scenario.Location.PlLineOffsetBelowDikeCrestMiddle = scenario.PlLineOffsetBelowDikeCrestMiddle; - } - if (scenario.PlLineOffsetFactorBelowShoulderCrest.HasValue) - { - scenario.Location.PlLineOffsetFactorBelowShoulderCrest = scenario.PlLineOffsetFactorBelowShoulderCrest; - } - if (scenario.UsePlLineOffsetBelowDikeCrestMiddle.HasValue) - { - scenario.Location.UsePlLineOffsetBelowDikeCrestMiddle = scenario.UsePlLineOffsetBelowDikeCrestMiddle; - } - if (scenario.UsePlLineOffsetFactorBelowShoulderCrest.HasValue) - { - scenario.Location.UsePlLineOffsetFactorBelowShoulderCrest = scenario.UsePlLineOffsetFactorBelowShoulderCrest; - } - if (scenario.HeadPl3.HasValue) - { - scenario.Location.HeadPl3 = scenario.HeadPl3.Value; - } - if (scenario.HeadPl4.HasValue) - { - scenario.Location.HeadPl4 = scenario.HeadPl4.Value; - } + // Save the results after each calculation, because these will be deleted in the next calculation + var calculationresults = new List(); - var selectedKernelType = StabilityKernelType.DamClassic; - var damProjectCalculationSpecification = damProjectData.DamProjectCalculationSpecification; - var spec = damProjectCalculationSpecification.DamCalculationSpecifications.First(); - if (spec != null) + foreach (var calculationSpecification in damProjectCalculationSpecification.DamCalculationSpecifications) { - selectedKernelType = spec.StabilityKernelType; - } - if (DetermineStabilityUpliftForScenarios(scenario, selectedKernelType)) - { + var selectedProbabilisticType = damProjectCalculationSpecification.SelectedProbabilisticType; + var analysisType = DamProjectCalculationSpecification.SelectedAnalysisType; - // Save the results after each calculation, because these will be deleted in the next calculation - var calculationresults = new List(); - - foreach (var calculationSpecification in damProjectCalculationSpecification.DamCalculationSpecifications) + Debug.WriteLine("Location '{0}', scenario '{1}' 10", scenarioName, scenarioId); + ValidateSpecification(); + if (IsStabilityBishopLiftVanCalculation(calculationSpecification)) { - var selectedProbabilisticType = damProjectCalculationSpecification.SelectedProbabilisticType; - var analysisType = DamProjectCalculationSpecification.SelectedAnalysisType; - - Debug.WriteLine("Location '{0}', scenario '{1}' 10", scenarioName, scenarioId); - ValidateSpecification(); - if (IsStabilityBishopLiftVanCalculation(calculationSpecification)) - { - Debug.WriteLine("Location '{0}', scenario '{1}' 11", scenarioName, scenarioId); - CalculateStabilityBishopUpliftvanForScenario(scenario, calculationSpecification, selectedProbabilisticType, analysisType); - } - else - { - Debug.WriteLine("Location '{0}', scenario '{1}' 15", scenarioName, scenarioId); - CalculateOneCalculationTypeForScenario(scenario, calculationSpecification, selectedProbabilisticType, analysisType); - } - Debug.WriteLine("Location '{0}', scenario '{1}' 20", scenarioName, scenarioId); - calculationresults.AddRange(scenario.CalculationResults); + Debug.WriteLine("Location '{0}', scenario '{1}' 11", scenarioName, scenarioId); + CalculateStabilityBishopUpliftvanForScenario(scenario, calculationSpecification, selectedProbabilisticType, analysisType); } - // Assign the combined results to the scenario - scenario.CalculationResults.Clear(); - scenario.CalculationResults.AddRange(calculationresults); + else + { + Debug.WriteLine("Location '{0}', scenario '{1}' 15", scenarioName, scenarioId); + CalculateOneCalculationTypeForScenario(scenario, calculationSpecification, selectedProbabilisticType, analysisType); + } + Debug.WriteLine("Location '{0}', scenario '{1}' 20", scenarioName, scenarioId); + calculationresults.AddRange(scenario.CalculationResults); } - + // Assign the combined results to the scenario + scenario.CalculationResults.Clear(); + scenario.CalculationResults.AddRange(calculationresults); } - catch (Exception exception) + + } + catch (Exception exception) + { + scenario.Errors.Add(exception.Message); + } + finally + { + if( oldLocation != null) { - scenario.Errors.Add(exception.Message); + scenario.Location = oldLocation; } - finally - { - if( oldLocation != null) - { - scenario.Location = oldLocation; - } - } - }); + } } private void CloneLocationOnScenario(Scenario scenario) { lock (lockObject) { - // TODO missing clone method for Location. This is a dirty way of performing a clone. - var locationUsedInCalculation = new XmlSerializer().SerializeToString(scenario.Location); - var location = new XmlDeserializer().XmlDeserializeFromString(locationUsedInCalculation); - scenario.Location = location; +// // TODO missing clone method for Location. This is a dirty way of performing a clone. +// var locationUsedInCalculation = new XmlSerializer().SerializeToString(scenario.Location); +// var location = new XmlDeserializer().XmlDeserializeFromString(locationUsedInCalculation); +// scenario.Location = location; ##Bka replace with object copier. } } @@ -434,7 +439,7 @@ } foreach (var errorMessage in damFailureMechanismeCalculator.ErrorMessages) { - LogManager.Messages.Add(errorMessage); + //LogManager.Messages.Add(errorMessage);##Bka } var recordIndex = 0; @@ -533,11 +538,11 @@ foreach (var error in scenario.Errors) { var logMessage = new LogMessage(LogMessageType.Error, null, error); - LogManager.Messages.Add(logMessage); + //LogManager.Messages.Add(logMessage);##Bka } foreach (var errorMessage in damFailureMechanismeCalculator.ErrorMessages) { - LogManager.Messages.Add(errorMessage); + // LogManager.Messages.Add(errorMessage);##Bka } foreach (var soilProfileProbability in scenario.Location.Segment.SoilProfileProbabilities) @@ -628,7 +633,7 @@ foreach (var error in scenario.Errors) { var logMessage = new LogMessage(LogMessageType.Error, null, error); - LogManager.Messages.Add(logMessage); + //LogManager.Messages.Add(logMessage); ##Bka } return res; } @@ -854,9 +859,9 @@ case PLLineCreationMethod.ExpertKnowledgeRRD: case PLLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD: return CreateAllPLLinesExpertKnowledge(out upliftSituation, waterLevel, waterLevelLow, location, soilProfileProbability, surfaceLine); - case PLLineCreationMethod.DupuitStatic: - string geometryDirectory = DamProject.ProjectWorkingPath; - return CreateAllPLLinesDupuit(out upliftSituation, location, soilProfileProbability, surfaceLine, geometryDirectory, waterLevel); +// case PLLineCreationMethod.DupuitStatic: +// string geometryDirectory = DamProjectData.ProjectWorkingPath; +// return CreateAllPLLinesDupuit(out upliftSituation, location, soilProfileProbability, surfaceLine, geometryDirectory, waterLevel); ##Bka case PLLineCreationMethod.DupuitDynamic: throw new DamCalculationException("PL-Line creation with DupuitDynamic not yet implemented"); default: @@ -875,33 +880,33 @@ /// Create PLLines with Dupuit model /// /// the created pl lines - private PLLines CreateAllPLLinesDupuit(out UpliftSituation upliftSituation, Location location, SoilGeometryProbability soilProfileProbability, - SurfaceLine2 surfaceLine, String geometryDirectory, double waterLevel) - { - var timeSerieIn = new TimeSerie(); - timeSerieIn.Entries.Add(new TimeSerieEntry(DateTime.Now, waterLevel)); - var plLinesCreatorDupuit = new PLLinesCreatorDupuit - { - Geometry2DData = Geometry2DDataCreator.CreateGeometry2DData(location, soilProfileProbability, surfaceLine, geometryDirectory), - SurfaceLine = location.LocalXZSurfaceLine2, - WaterLevelTimeserie = timeSerieIn, - SoilList = location.SoilList, - PolderLevel = location.PolderLevel, - IsReverseLayerOrder = true - }; +// private PLLines CreateAllPLLinesDupuit(out UpliftSituation upliftSituation, Location location, SoilGeometryProbability soilProfileProbability, +// SurfaceLine2 surfaceLine, String geometryDirectory, double waterLevel) +// { +// var timeSerieIn = new TimeSerie(); +// timeSerieIn.Entries.Add(new TimeSerieEntry(DateTime.Now, waterLevel)); +// var plLinesCreatorDupuit = new PLLinesCreatorDupuit +// { +// Geometry2DData = Geometry2DDataCreator.CreateGeometry2DData(location, soilProfileProbability, surfaceLine, geometryDirectory), +// SurfaceLine = location.LocalXZSurfaceLine2, +// WaterLevelTimeserie = timeSerieIn, +// SoilList = location.SoilList, +// PolderLevel = location.PolderLevel, +// IsReverseLayerOrder = true +// }; +// +// upliftSituation.Pl3HeadAdjusted = 0; +// upliftSituation.Pl3LocationXMinUplift = 0; +// upliftSituation.Pl3MinUplift = 0; +// upliftSituation.Pl4HeadAdjusted = 0; +// upliftSituation.Pl4LocationXMinUplift = 0; +// upliftSituation.Pl4MinUplift = 0; +// upliftSituation.IsUplift = false; // must be determined later on; just to avoid compiler error +// plLinesCreatorDupuit.CreateAllPlLines(); +// +// return null; +// } - upliftSituation.Pl3HeadAdjusted = 0; - upliftSituation.Pl3LocationXMinUplift = 0; - upliftSituation.Pl3MinUplift = 0; - upliftSituation.Pl4HeadAdjusted = 0; - upliftSituation.Pl4LocationXMinUplift = 0; - upliftSituation.Pl4MinUplift = 0; - upliftSituation.IsUplift = false; // must be determined later on; just to avoid compiler error - plLinesCreatorDupuit.CreateAllPlLines(); - - return null; - } - /// /// Create PLLines with expert knowledge /// @@ -944,7 +949,6 @@ plLinesCreator.Gauges = location.Gauges; plLinesCreator.GaugeMissVal = location.GaugeMissVal; plLinesCreator.IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true; // for stability this must set to true - plLinesCreator.SoilBaseDB = location.SoilbaseDB; plLinesCreator.SoilList = location.SoilList; plLinesCreator.DikeEmbankmentMaterial = location.SoilList.GetSoilByName(location.DikeEmbankmentMaterial); plLinesCreator.PlLineOffsetBelowDikeTopAtRiver = location.PlLineOffsetBelowDikeTopAtRiver; @@ -957,15 +961,15 @@ plLinesCreator.UsePlLineOffsetFactorBelowShoulderCrest = location.UsePlLineOffsetFactorBelowShoulderCrest; plLinesCreator.XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin; - PLLines plLines = plLinesCreator.CreateAllPLLines(location); + //PLLines plLines = plLinesCreator.CreateAllPLLines(location); ##Bka upliftSituation.Pl3HeadAdjusted = plLinesCreator.Pl3HeadAdjusted; upliftSituation.Pl3LocationXMinUplift = plLinesCreator.Pl3LocationXMinUplift; upliftSituation.Pl3MinUplift = plLinesCreator.Pl3MinUplift; upliftSituation.Pl4HeadAdjusted = plLinesCreator.Pl4HeadAdjusted; upliftSituation.Pl4LocationXMinUplift = plLinesCreator.Pl4LocationXMinUplift; upliftSituation.Pl4MinUplift = plLinesCreator.Pl4MinUplift; upliftSituation.IsUplift = false; // must be determined later on; just to avoid compiler error - return plLines; + return null; //plLines; ##Bka } } } \ No newline at end of file Fisheye: Tag 330 refers to a dead (removed) revision in file `dam engine/branches/Initial Source/Deltares.DamEngine.Controllers/StabilityServiceAgent.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamProjectCalculatorCsvExportDataBuilder.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamProjectCalculatorCsvExportDataBuilder.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamProjectCalculatorCsvExportDataBuilder.cs (revision 330) @@ -0,0 +1,118 @@ +// 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.Text; +using Deltares.DamEngine.Data.Design; +using Deltares.DamEngine.Data.General; + +namespace Deltares.DamEngine.Calculators.General +{ + /// + /// This class helps to build cvs export data. Everytime the builder is ended by calling Build() method, + /// the builder is reset and can be used to construct a new CvsExportData item. + /// + internal class DamProjectCalculatorCsvExportDataBuilder + { + private Dike Dike { get; set; } + private Scenario Scenario { get; set; } + private DamFailureMechanismeCalculationSpecification FailureMechanismSystemType { get; set; } + private AnalysisType AnalysisType { get; set; } + private ProbabilisticType ProbabilisticType { get; set; } + private StringBuilder Message { get; set; } + + /// + /// Instantiate a new instance of the with general settings which to use in creating + /// . + /// + /// The for which to create . + /// The for which to create . + /// The for which to create . + /// The for which to create . + /// The for which to create + public DamProjectCalculatorCsvExportDataBuilder(Dike dike, Scenario scenario, DamFailureMechanismeCalculationSpecification damFailureMechanismCalculationSpecification, AnalysisType analysisType, ProbabilisticType probabilisticType) + { + Dike = dike; + Scenario = scenario; + FailureMechanismSystemType = damFailureMechanismCalculationSpecification; + AnalysisType = analysisType; + ProbabilisticType = probabilisticType; + Message = new StringBuilder(); + } + + /// + /// Returns a new instance of . Messages that were added using are added to the + /// and the message queue is cleared. + /// + /// The for which to create this . + /// The to set for the to be created . Default is the 0th . + /// The newly constructed with messages appended using . + public CsvExportData Build(SoilGeometryProbability soilGeometryProbability, StabilityKernelType kernelType = (StabilityKernelType) 0) + { + return Build(soilGeometryProbability, kernelType, 0); + } + + /// + /// Returns a new instance of . Messages that were added using are added to the + /// and the message queue is cleared. + /// + /// The for which to create this . + /// An optional index to associate the with some other object of a list. + /// The newly constructed with messages appended using . + public CsvExportData Build(SoilGeometryProbability soilGeometryProbability, int index) + { + return Build(soilGeometryProbability, 0, index); + } + + private CsvExportData Build(SoilGeometryProbability soilGeometryProbability, StabilityKernelType kernelType, int index) + { + var data = new CsvExportData( + Message.ToString(), + Dike, + FailureMechanismSystemType, + Scenario, + soilGeometryProbability.SoilProfile, + soilGeometryProbability.SoilGeometry2DName, + AnalysisType, + index, + ProbabilisticType); + data.SelectedStabilityKernelType = kernelType; + + Message.Clear(); + + return data; + } + + /// + /// Append a new message to the message queue. + /// + /// The messages to add to the queue. + /// This instance of the so that consecutive calls to methods + /// of can be chained. + public DamProjectCalculatorCsvExportDataBuilder Append(params object[] messageParts) + { + foreach (var messagePart in messageParts) + { + Message.Append(messagePart); + } + return this; + } + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Design/SurfaceLineHeightAdapter.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Design/SurfaceLineHeightAdapter.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Design/SurfaceLineHeightAdapter.cs (revision 330) @@ -0,0 +1,180 @@ +// 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 Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.Geometry; +using Deltares.DamEngine.Data.Geotechnics; + +namespace Deltares.DamEngine.Calculators.General +{ + public class SurfaceLineHeightAdapterException : Exception + { + public SurfaceLineHeightAdapterException(string message) : base(message) { } + } + + public class SurfaceLineHeightAdapter : SurfaceLineAdapter + { + public SurfaceLineHeightAdapter(SurfaceLine2 surfaceLine, Location location) : base(surfaceLine, location) + { + } + + /// + /// Constructs a new surface line with a new height + /// + /// + /// There are a few scenarios of that will be handled: + /// - one without a shoulder inside + /// - one with a shoulder inside but the adaption will remove the shoulder completly + /// - one with a shoulder but a part of the shoulder remains intact + /// - one where the new top falls completely above the old top + /// + /// The new height + /// The adapted surface line + /// + public SurfaceLine2 ConstructNewSurfaceLine(double newDikeHeight) + { + + //Input data + GeometryPoint pointAtTopRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver); + GeometryPoint pointAtTopPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); + GeometryPoint pointDikeToeInward = surfaceLine.GetDikeToeInward(); + GeometryPoint startingPoint = surfaceLine.GetStartingPoint(); + + surfaceLine.RemoveSegmentBetween(startingPoint.X, pointAtTopRiver.X); + GeometryPoint newPointAtTopRiver; + GeometryPoint oldPointAtTopRiver = null; + if (Location.UseNewDikeSlopeOutside) + { + var newOutsideSlopePoint = new GeometryPoint + { + X = pointAtTopRiver.X + 100, + Z = pointAtTopRiver.Z + 100*Location.NewDikeSlopeOutside + }; + newPointAtTopRiver = LineHelper.GetIntersectionPointWithExtrapolation(pointAtTopRiver, newOutsideSlopePoint, + new GeometryPoint(pointAtTopRiver.X, newDikeHeight), + new GeometryPoint(pointAtTopPolder.X, newDikeHeight)); + oldPointAtTopRiver = new GeometryPoint {X = pointAtTopRiver.X, Z = pointAtTopRiver.Z}; + } + else + { + newPointAtTopRiver = LineHelper.GetIntersectionPointWithExtrapolation(startingPoint,pointAtTopRiver, + new GeometryPoint(pointAtTopRiver.X, newDikeHeight), + new GeometryPoint(pointAtTopPolder.X, newDikeHeight)); + } + // Determine the new point at DIKE TOP RIVER + + + double dikeTopWidth = pointAtTopPolder.X - pointAtTopRiver.X; + if (Location.UseNewDikeTopWidth) + { + dikeTopWidth = Location.NewDikeTopWidth; + } + + // Determine the new point at DIKE TOP POLDER + GeometryPoint newPointAtTopPolder = new GeometryPoint(newPointAtTopRiver.X + dikeTopWidth, newDikeHeight); + + var slopeTangentInside = (pointAtTopPolder.Z - pointDikeToeInward.Z) / (pointDikeToeInward.X - pointAtTopPolder.X); + if (Location.UseNewDikeSlopeInside) + { + slopeTangentInside = Location.NewDikeSlopeInside; + } + // check case where the new top falls completely above the old top + var intersectionPointDikeTop = IntersectionpointWithOldDikeTop(newPointAtTopPolder, slopeTangentInside); + if (intersectionPointDikeTop != null) + { + // Remove all points between old dike top river and old dike top polder + surfaceLine.RemoveSegmentBetween(pointAtTopRiver.X, pointAtTopPolder.X); + // Add new dike top river, new dike top polder + surfaceLine.AddCharacteristicPoint(newPointAtTopRiver, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.AddCharacteristicPoint(newPointAtTopPolder, CharacteristicPointType.DikeTopAtPolder); + // check if intersection point equals old dike top polder, if so the ready else add intersection point as normal point + if (!pointAtTopPolder.LocationEquals(intersectionPointDikeTop)) + { + surfaceLine.EnsurePoint(intersectionPointDikeTop.X, intersectionPointDikeTop.Z); + } + surfaceLine.SortPoints(); + return surfaceLine; + } + + // Remove points on inside slope + surfaceLine.RemoveSegmentBetween(pointAtTopPolder.X, pointDikeToeInward.X); + // Store the ditch (if any) + var ditchDefinition = GetDitchDefinition(); + // Delete the ditch from the surfaceline (if any) + RemoveExistingDitch(ditchDefinition); + // Adjust for the new slope + var slopePoint = ReplaceBaseInsideForNewSlope(newPointAtTopPolder, slopeTangentInside); + // Reset pointDikeToeInward for new position + pointDikeToeInward = surfaceLine.GetDikeToeInward(); + // Remove all points between "old" dike top river side and new toe inward + surfaceLine.RemoveSegmentBetween(pointAtTopRiver.X, pointDikeToeInward.X); + if (slopePoint != null) + { + // if the slope point exists (new end point of slope coincides with shouldertopinside), it has to be + // re-added as "normal" point because it was deleted in the former RemoveSegmentBetween. + surfaceLine.AddCharacteristicPoint(slopePoint, CharacteristicPointType.None); + } + // Adjust position of "old" dike top river + surfaceLine.EnsurePointOfType(newPointAtTopRiver.X, newPointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + if (Location.UseNewDikeSlopeOutside) + { + // Re-add the old dike top river as "normal" point + surfaceLine.AddCharacteristicPoint(oldPointAtTopRiver, CharacteristicPointType.None); + } + // Add the new dike top at polder side + surfaceLine.EnsurePointOfType(newPointAtTopPolder.X, newPointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + // Restore Ditch (if any) + RestoreDitch(ditchDefinition); + // Restore traffic load + RestoreTrafficLoad(); + surfaceLine.SortPoints(); + + return surfaceLine; + } + + /// + /// Tries to find the intersection point between the old dike top and the new inside slope starting at the new + /// dike top at polder side. + /// + /// + /// + /// The intersection point when found else null + private GeometryPoint IntersectionpointWithOldDikeTop(GeometryPoint newPointAtTopPolder, double slopeTangent) + { + GeometryPoint res = null; + var newPoint = new GeometryPoint + { + X = newPointAtTopPolder.X + 100, + Z = newPointAtTopPolder.Z - 100*slopeTangent + }; + GeometryPoint dikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); + var ip = LineHelper.GetIntersectionPointWithExtrapolation(newPointAtTopPolder, newPoint, + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver), + dikeTopAtPolder); + if (ip != null && ip.X <= dikeTopAtPolder.X) + { + res = ip; + } + return res; + } + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj =================================================================== diff -u -r276 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 276) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 330) @@ -41,13 +41,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -56,7 +83,6 @@ - Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj =================================================================== diff -u -r316 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (.../Deltares.DamEngine.Data.csproj) (revision 316) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (.../Deltares.DamEngine.Data.csproj) (revision 330) @@ -96,6 +96,7 @@ + @@ -149,12 +150,11 @@ - - + Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Interfaces/DGSStandardDLLInterface.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Interfaces/DGSStandardDLLInterface.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Interfaces/DGSStandardDLLInterface.cs (revision 330) @@ -0,0 +1,131 @@ +// 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.Runtime.InteropServices; + +namespace Deltares.DamEngine.Calculators.Interfaces +{ + /// + /// Structure for dll information + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct DllVersionInfoStructure + { + /// + /// Size of the structure, in bytes + /// + public uint CbSize; + + /// + /// Major version of the DLL + /// + public uint DwMajorVersion; + + /// + /// Minor version of the DLL + /// + public uint DwMinorVersion; + + /// + /// Build number of the DLL + /// + public uint DwBuildNumber; + + /// + /// Identifies the platform for which the DLL was built + /// + public uint DwPlatformID; + } + + /// + /// The standard DLL interface for DGS. + /// + public class DgsStandardDllInterface + { + /// + /// No Licence error + /// + public const int DllUErrorNoLicense = 1; + + /// + /// User has aborted error + /// + public const int DllErrorUserAborted = 2; + + /// + /// Non compliant xml error + /// + public const int DllErrorNonCompliantXml = 3; + + /// + /// Invalid input data error + /// + public const int DllErrorInvalidInputData = 4; + + /// + /// Handled fatal error + /// + public const int DllErrorHandledFatal = 5; + + /// + /// Unhandled fatal error + /// + public const int DllErrorUnhandledFatal = 6; + + /// + /// Invalid handle for dll error + /// + public const int DllErrorInvalidHandle = 7; + + /// + /// Output buffer too small error + /// + public const int DllErrorOutputBufferTooSmall = 8; + + /// + /// Error constants + /// + public static int DllErrorNone = 0; + + /// + /// Used to hold the last error encountered + /// + public static int DllErrorLastErrorCode = 0; + + /// + /// Example! (remove this wrapper if not needed) + /// + /// + public string GetDllVersion() + { + return "To be implemented"; + } + + /// + /// List of errormessages + /// + /// + public string ErrorMessage() + { + return "To be implemented"; + } + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityCalculator.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityCalculator.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityCalculator.cs (revision 330) @@ -0,0 +1,1230 @@ +// 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.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Security.Policy; +using System.Text.RegularExpressions; +using System.Xml.Linq; +using System.Xml.Serialization; +using Deltares.DamEngine.Calculators.Uplift; +using Deltares.DamEngine.Data.Design; +using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.General.Gauges; +using Deltares.DamEngine.Data.General.PlLines; +using Deltares.DamEngine.Data.General.Results; +using Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.Data.Standard.Calculation; +using Deltares.DamEngine.Data.Standard.Language; +using Deltares.DamEngine.Data.Standard.Logging; + +namespace Deltares.DamEngine.Calculators.Stability +{ + + public class StabilityCalculator : IDisposable + { + protected ModelParametersForPLLines modelParametersForPLLines; + private ProgramType programType; + private double trafficLoad; + private double minimalCircleDepth; + private double requiredSafetyFactor; + private string mstabProgramPath; + private string slopeWProgramPath; + private FailureMechanismeParamatersMStab failureMechanismeParamatersMStab; + private IList gaugePLLines; + private IList gauges; + private string stabilityProjectFilename = ""; + private List errorMessages = new List(); + + public const string StabilitySubDir = @"Stability\"; + + public StabilityCalculator(FailureMechanismeParamatersMStab failureMechanismeParamatersMStab, + ProgramType programType, + ModelParametersForPLLines modelParametersForPLLines, double trafficLoad, double minimalCircleDepth, + double requiredSafetyFactor, string mstabProgramPath, string slopeWProgramPath, + IList gaugePLLines, + IList gauges, SoilList soilList, ProbabilisticType probabilisticType) + { + this.programType = programType; + this.modelParametersForPLLines = modelParametersForPLLines; + this.trafficLoad = trafficLoad; + this.minimalCircleDepth = minimalCircleDepth; + this.requiredSafetyFactor = requiredSafetyFactor; + this.mstabProgramPath = mstabProgramPath; + this.slopeWProgramPath = slopeWProgramPath; + // need to have own instance of failureMechanismeParamatersMStab because the calculation + // makes changes to this object (e.g. failureMechanismeParamatersMStab.PLLines) + // This will not function correctly when the calculations are performed + // multi threaded (MWDAM-568) + this.failureMechanismeParamatersMStab = failureMechanismeParamatersMStab.Clone(); + this.gaugePLLines = gaugePLLines; + this.gauges = gauges; + this.SoilList = soilList; + ProbabilisticType = probabilisticType; + CalculationBaseDirectory = ""; + } + + public string CalculationBaseDirectory { get; set; } + public SoilList SoilList { get; set; } + public ProbabilisticType ProbabilisticType { get; set; } + public static string ModelSubDirectory = ""; + private MStabProject dotNetMstabProjectResults; + public PhreaticAdaptionType? NWOPhreaticAdaption { get; set; } + + /// + /// Create PLLines with selected model + /// + /// The location. + /// The surface line. + /// The soil profile. + /// Name of the soil geometry2 d. + /// The waterlevel. + /// The waterlevel low. + /// + private PLLines CreateAllPLLines(Location location, SurfaceLine2 surfaceLine, SoilProfile soilProfile, + string soilGeometry2DName, double waterlevel, double? waterlevelLow) + { + // switch (location.PLLineCreationMethod) + // { + // case PLLineCreationMethod.ExpertKnowledgeLinearInDike: + // case PLLineCreationMethod.ExpertKnowledgeRRD: + // case PLLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD: + // return CreateAllPLLinesExpertKnowledge(location, surfaceLine, soilProfile, soilGeometry2DName, waterlevel, waterlevelLow); + // case PLLineCreationMethod.DupuitStatic: + // return CreateAllPLLinesDupuit(); + // case PLLineCreationMethod.DupuitDynamic: + // throw new StabilityCalculationException("PL-Line creation with DupuitDynamic not yet implemented"); + // default: + // return null; + // } + return null; + } + + /// + /// Create PLLines with Dupuit model + /// + /// + private PLLines CreateAllPLLinesDupuit() + { + return null; + } + + /// + /// Create PLLines with expert knowledge + /// + /// The location. + /// The surface line. + /// The soil profile. + /// Name of the soil geometry2 d. + /// The waterlevel. + /// The waterlevel low. + /// +// private PLLines CreateAllPLLinesExpertKnowledge(Location location, SurfaceLine2 surfaceLine, SoilProfile soilProfile, +// string soilGeometry2DName, double waterlevel, double? waterlevelLow) +// { +// PLLines plLines = null; +// +// if (surfaceLine != null && surfaceLine.HasDike()) +// { +// PLLinesCreator plLineCreator = new PLLinesCreator(); +// plLineCreator.SurfaceLine = surfaceLine; +// plLineCreator.WaterLevelRiverHigh = waterlevel; +// plLineCreator.WaterLevelRiverLow = waterlevelLow; +// plLineCreator.IsUseLowWaterLevel = (failureMechanismeParamatersMStab.MStabParameters.GridPosition == MStabGridPosition.Left); +// plLineCreator.WaterLevelPolder = location.PolderLevel; +// plLineCreator.HeadInPLLine2 = location.HeadPL2; +// plLineCreator.HeadInPLLine3 = location.HeadPl3; +// plLineCreator.HeadInPLLine4 = location.HeadPl4; +// plLineCreator.ModelParametersForPLLines = this.modelParametersForPLLines; +// SoilProfile1D profile1D = soilProfile as SoilProfile1D; +// if (profile1D != null) +// { +// plLineCreator.SoilProfile = profile1D; +// plLineCreator.SoilGeometryType = SoilGeometryType.SoilGeometry1D; +// } +// else +// { +// plLineCreator.SoilGeometryType = SoilGeometryType.SoilGeometry2D; +// string mapForSoilGeometries2D = location.MapForSoilGeometries2D; +// soilGeometry2DName = Path.Combine(Path.Combine(DamProject.ProjectMap, mapForSoilGeometries2D), soilGeometry2DName); +// plLineCreator.SoilGeometry2DName = soilGeometry2DName; +// plLineCreator.SoilList = this.SoilList; +// plLineCreator.DikeEmbankmentMaterial = +// this.SoilList.GetSoilByName(location.DikeEmbankmentMaterial); +// } +// plLineCreator.GaugePLLines = this.gaugePLLines; +// plLineCreator.Gauges = this.gauges; +// plLineCreator.IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true; +// // for stability this must be set to true +// plLineCreator.PlLineOffsetBelowDikeTopAtRiver = location.PlLineOffsetBelowDikeTopAtRiver; +// plLineCreator.PlLineOffsetBelowDikeTopAtPolder = location.PlLineOffsetBelowDikeTopAtPolder; +// plLineCreator.PlLineOffsetBelowShoulderBaseInside = location.PlLineOffsetBelowShoulderBaseInside; +// plLineCreator.PlLineOffsetBelowDikeToeAtPolder = location.PlLineOffsetBelowDikeToeAtPolder; +// plLineCreator.PlLineOffsetBelowDikeCrestMiddle = location.PlLineOffsetBelowDikeCrestMiddle; +// plLineCreator.PlLineOffsetFactorBelowShoulderCrest = location.PlLineOffsetFactorBelowShoulderCrest; +// plLineCreator.UsePlLineOffsetBelowDikeCrestMiddle = location.UsePlLineOffsetBelowDikeCrestMiddle; +// plLineCreator.UsePlLineOffsetFactorBelowShoulderCrest = location.UsePlLineOffsetFactorBelowShoulderCrest; +// plLineCreator.NWOPhreaticAdaption = NWOPhreaticAdaption; +// plLineCreator.XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin; +// +// plLines = plLineCreator.CreateAllPLLines(location); +// } +// +// return plLines; +// } + + public string GetStabilityCalculationDirectory() + { + string stabilityDirectory = GetStabilityCalculationBaseDirectory(); + if (StabilityCalculator.ModelSubDirectory != "") + stabilityDirectory = Path.Combine(stabilityDirectory, StabilityCalculator.ModelSubDirectory); + if (!Directory.Exists(stabilityDirectory)) + Directory.CreateDirectory(stabilityDirectory); + return stabilityDirectory; + } + + /// + /// Get the directory where to create the MStab project files + /// + /// + private string GetStabilityCalculationBaseDirectory() + { + if (CalculationBaseDirectory == "") + { + CalculationBaseDirectory = DamProjectData.ProjectWorkingPath; + } + return Path.Combine(CalculationBaseDirectory, StabilitySubDir); + } + + /// + /// + /// + /// + /// + /// + public void ConsistencyCheck(Scenario scenario, SoilProfile1D soilProfile, string soilGeometry2DName) + { + if (soilProfile != null) + { + if (soilProfile.BottomAquiferLayer == null) + { + throw new DamFailureMechanismeCalculatorException( + String.Format("Soilprofile '{0}' does not contain aquifer layers.", soilProfile.Name)); + } + } + } + +// private void AddForbiddenZoneToMstabProject(MStabProject mStabProject, Scenario scenario, SurfaceLine2 surfaceLine) +// { +// if (failureMechanismeParamatersMStab.MStabParameters.CalculationOptions.ZonesType.Equals( +// MStabZonesType.ForbiddenZone)) +// { +// CreateForbiddenZone(scenario, surfaceLine); +// AddMissingSlipPlaneConstraintInfo(mStabProject.Stability.SlipPlaneConstraints); +// } +// } + +// private void CalculateType(string stabilityProjectFilename, Scenario scenario, SoilProfile1D soilProfile, +// string soilGeometry2DName, +// StabilityServiceAgent stabilityServiceAgent, double riverLevel, MStabDesignEmbankment mstabDesignEmbankment) +// { +// +// // +// // Here start of implementation of DesignPoint Probabilistic Calculation +// // Perform DesignPoint Probabilistic Calculation when this.ProbabilisticType == ProbabilisticType.ProbabilisticAdvanced +// // +// if (dotNetMstabProjectResults != null) +// { +// dotNetMstabProjectResults.Dispose(); +// dotNetMstabProjectResults = null; +// } +// failureMechanismeParamatersMStab.MStabParameters.CalculationOptions = new MStabCalculationOptions +// { +// MinimalCircleDepth = this.minimalCircleDepth, +// ZonesType = scenario.Location.StabilityZoneType +// }; +// SoilProfile profile; +// var surfaceLine = scenario.GetMostRecentSurfaceLine(soilProfile, +// Path.GetFileName(soilGeometry2DName)); +// //create mstabproj using .NET, without using delphi dll and xml files +// if (SelectedStabilityKernelType == StabilityKernelType.AdvancedWti) +// { +// profile = GetSoilProfileByType(soilProfile, scenario.Location.MapForSoilGeometries2D, soilGeometry2DName); +// UpdateProfileSoilsToProjectSoils(profile); +// +// var parameterValues = GetStabilityProjectParameterValues(); +// var stabilityProjectObjectCreator = new StabilityProjectObjectCreator(); +// MStabProject mStabProject = stabilityProjectObjectCreator.CreateMacroStabilityProject(scenario, profile, failureMechanismeParamatersMStab, riverLevel, parameterValues); +// AddForbiddenZoneToMstabProject(mStabProject, scenario, surfaceLine); +// RunStabilityCalculationWtiKernel(mStabProject); +// return; +// } +// //use mstab stability kernel, create mstabproj using .NET +// if (SelectedStabilityKernelType == StabilityKernelType.AdvancedDotNet) +// { +// profile = GetSoilProfileByType(soilProfile, scenario.Location.MapForSoilGeometries2D, soilGeometry2DName); +// UpdateProfileSoilsToProjectSoils(profile); +// +// var parameterValues = GetStabilityProjectParameterValues(); +// var stabilityProjectObjectCreator = new StabilityProjectObjectCreator(); +// MStabProject mStabProject = stabilityProjectObjectCreator.CreateMacroStabilityProject(scenario, +// profile, failureMechanismeParamatersMStab, riverLevel, parameterValues); +// AddForbiddenZoneToMstabProject(mStabProject, scenario, surfaceLine); +// var projectString = SaveStabilityProjectFileToString(mStabProject); +// +// RunMstabStabilityCalculation(projectString); +// return; +// } +// +// XDocument mstabXML = CreateMStabXmlDoc(stabilityProjectFilename, scenario, soilProfile, soilGeometry2DName, +// riverLevel, mstabDesignEmbankment, surfaceLine); +// mstabXML.Save(stabilityProjectFilename + ".xml"); +// +// stabilityServiceAgent.CreateProjectFile(mstabXML.ToString()); +// // use the current stability kernel +// if (SelectedStabilityKernelType == StabilityKernelType.DamClassic) +// { +// if (programType == ProgramType.SlopeW) +// { +// stabilityServiceAgent.CalculateSlopeWProject(stabilityProjectFilename); +// } +// else +// { +// stabilityServiceAgent.CalculateMStabProject(stabilityProjectFilename); +// } +// } +// // use the converted .NET stability kernel +// else if (SelectedStabilityKernelType == StabilityKernelType.DamClassicDotNet) +// { +// RunMstabStabilityCalculation(stabilityProjectFilename); +// } +// +// // use the WTI Stability Kernel, create mstabproj using delphi +// else if (SelectedStabilityKernelType == StabilityKernelType.DamClassicWti) +// { +// MStabProject mStabProject = ReadStabilityModel(stabilityProjectFilename); +// mStabProject.Stability.Location.WaterLevelRiver = riverLevel; +// AddMissingSlipPlaneConstraintInfo(mStabProject.Stability.SlipPlaneConstraints); +// mStabProject.Stability.SurfaceLine2 = surfaceLine; +// RunStabilityCalculationWtiKernel(mStabProject); +// } +// } + + /// + /// Updates the profile soils to project soils. + /// + /// The profile. + /// + private void UpdateProfileSoilsToProjectSoils(SoilProfile profile) + { + // Assign the soils from the soillist to the soils in the profile + var soilProfile2D = profile as SoilProfile2D; + if (soilProfile2D != null) + { + foreach (var surface in soilProfile2D.Surfaces) + { + var soil = SoilList.GetSoilByName(surface.Soil.Name); + if (soil == null) + { + throw new StabilityCalculationException(String.Format("No matching soil found for {0}", surface.Soil.Name)); + } + surface.Soil = soil; + } + } + else + { + var soilProfile1D = profile as SoilProfile1D; + if (soilProfile1D != null) + { + foreach (var layer in soilProfile1D.Layers) + { + var soil = SoilList.GetSoilByName(layer.Soil.Name); + if (soil == null) + { + throw new StabilityCalculationException(String.Format("No matching soil found for {0}", layer.Soil.Name)); + } + layer.Soil = soil; + } + } + else + { + throw new StabilityCalculationException(String.Format("Profile '{0}' has unexpected soilprofile type ", profile.Name)); + } + } + } + +// private void AddMissingSlipPlaneConstraintInfo(SlipplaneConstraints slipPlaneConstraints) +// { +// slipPlaneConstraints.CreateZones = +// failureMechanismeParamatersMStab.MStabParameters.ZonesType == MStabZonesType.ForbiddenZone; +// if (slipPlaneConstraints.CreateZones) +// { +// slipPlaneConstraints.SlipPlaneMinDepth = minimalCircleDepth; +// +// if (failureMechanismeParamatersMStab.MStabParameters.ForbiddenZone.IsXEntryMaxUsed) +// { +// slipPlaneConstraints.XEntryMax = failureMechanismeParamatersMStab.MStabParameters.ForbiddenZone.XEntryMax; +// } +// else +// { +// slipPlaneConstraints.XEntryMax = double.NaN; +// } +// +// if (failureMechanismeParamatersMStab.MStabParameters.ForbiddenZone.IsXEntryMinUsed) +// { +// slipPlaneConstraints.XEntryMin = failureMechanismeParamatersMStab.MStabParameters.ForbiddenZone.XEntryMin; +// } +// else +// { +// slipPlaneConstraints.XEntryMin = double.NaN; +// } +// } +// } + +// private static SoilProfile GetSoilProfileByType(SoilProfile1D soilProfile, string mapForSoilGeometries2D, string soilGeometry2DName) +// { +// SoilProfile profile = null; +// if (soilProfile != null) +// { +// profile = soilProfile; +// } +// else +// { +// var projDir = Path.GetDirectoryName(DamProjectData.ProjectWorkingPath); +// var fullPath = Path.Combine(projDir, mapForSoilGeometries2D, Path.GetFileName(soilGeometry2DName)); +// // Bka: for now, see if there is a dsx version too and if so prefer that. +// var dsxPath = Path.ChangeExtension(fullPath, ".dsx"); +// MStabProject mStab = null; +// //if (soilGeometry2DName.EndsWith(".dsx", StringComparison.OrdinalIgnoreCase)) +// if (File.Exists(dsxPath)) +// { +// try +// { +// var xmlDeserializer = new XmlDeserializer(); +// mStab = (MStabProject) xmlDeserializer.XmlDeserialize(dsxPath, typeof (MStabProject)); +// } +// catch (Exception ex) +// { +// LogManager.Add(new LogMessage(LogMessageType.Error, typeof (Converter), ex.Message)); +// } +// if (mStab != null) +// { +// profile = mStab.Stability.SoilProfile; +// mStab.Dispose(); +// } +// } +// else +// { +// var converter = new Converter(); +// mStab = new MStabProject(); +// mStab.Stability = converter.ConvertClassicMStab(fullPath); +// if (mStab.Stability.SoilProfile.Surfaces != null && mStab.Stability.SoilProfile.Surfaces.Count > 0) +// { +// // Ensure that the bottom layer of the geometry is seen as Aquifer. +// // There is no other way to get aquifer information as Delphi DGS does not work with aquifers and also not +// // with soiltypes so you can not derive anything from that too. +// mStab.Stability.SoilProfile.Surfaces[0].IsAquifer = true; +// } +// profile = mStab.Stability.SoilProfile; +// mStab.Dispose(); +// } +// } +// return profile; +// } + + /// + /// get stability project input parameters from DAM input + /// + /// +// private StabilityProjectParameterValues GetStabilityProjectParameterValues() +// { +// StabilityProjectParameterValues parameterValues = new StabilityProjectParameterValues(); +// parameterValues.MinimalCircleDepth = minimalCircleDepth; +// parameterValues.TrafficLoad = trafficLoad; +// parameterValues.PhreaticAdaptionType = NWOPhreaticAdaption != null +// ? (PhreaticAdaptionType)NWOPhreaticAdaption +// : PhreaticAdaptionType.None; +// parameterValues.PLlineCreationMethod = modelParametersForPLLines.PLLineCreationMethod; +// return parameterValues; +// } + + /// + /// run stability calculation using WTI stability kernel + /// + /// +// private void RunStabilityCalculationWtiKernel(MStabProject mStabProject) +// { +// StabilityModel stabilityModel = mStabProject.Stability; +// stabilityModel.CalculationModel = CalculationModel.RTO; +// var calculation = new Stability.Calculation2.StabilityCalculation(); +// calculation.RunCalculation(stabilityModel); +// // Todo mstabproject still to be filled with the results from the stabilityModel calculation. +// if (stabilityModel.MinimumSafetyCurve != null) +// { +// mStabProject.Result = CalculationResult.Succeeded; +// mStabProject.SlidingData = new SlidingModel() { CurrentZone = new Zone() { MinimumSafetyCurve = stabilityModel.MinimumSafetyCurve } }; +// +// } +// dotNetMstabProjectResults = mStabProject; +// } + + /// + /// run stability calculation using classic .NET kernel + /// + /// +// private void RunMstabStabilityCalculation(string projectString) +// { +// using (var calculation = new Stability.Calculation.StabilityCalculation()) +// { +// CalculationResult loadResult = calculation.Load(projectString); +// MStabProject loadedMStabProject = calculation.ClaimLoadedMStabProject(); +// if (loadResult == CalculationResult.Succeeded) +// { +// StabilityModel stabilityModel = loadedMStabProject.Stability; +// stabilityModel.CalculationModel = CalculationModel.DSerie; +// CalculationResult runResult = calculation.Run(); +// if (runResult == CalculationResult.Succeeded) +// { +// string results = null; +// CalculationResult calculationResult = calculation.GetResults(ref results); +// if (calculationResult == CalculationResult.Succeeded) +// { +// loadedMStabProject.ProcessResults(results); +// dotNetMstabProjectResults = loadedMStabProject; +// } +// else +// { +// loadedMStabProject.Dispose(); +// throw new DamFailureMechanismeCalculatorException(calculation.Messages[0].Message); +// } +// } +// } +// } +// } + + public MStabProject GetDotNetStabilityKernelResults() + { + return dotNetMstabProjectResults; + } + +// private MStabProject ReadStabilityModel(string fileName) +// { +// MStabProject project = null; +// DataEventPublisher.InvokeWithoutPublishingEvents(() => +// { +// if (!fileName.EndsWith(".dsx")) +// { +// var converter = new Converter(); +// project = new MStabProject(); +// project.Stability = converter.ConvertClassicMStab(fileName); +// } +// else +// { +// XmlDeserializer deserializer = new XmlDeserializer(); +// project = (MStabProject)deserializer.XmlDeserialize(fileName, typeof(MStabProject)); +// } +// }); +// +// return project; +// } + + /// + /// Determine a filename based on the different inout parameters + /// + /// + /// + /// + /// + /// + public static string DetermineCalculationFilename(string locationName, string scenarioName, + string soilGeometryName, int iterationIndex) + { + string calculationName; + if (iterationIndex < 0) + { + calculationName = String.Format("Loc({0})_Sce({1})_Pro({2})", locationName, scenarioName, + soilGeometryName); + } + else + { + calculationName = String.Format("Loc({0})_Sce({1})_Pro({2})_Ite({3})", locationName, scenarioName, + soilGeometryName, iterationIndex); + } + return Regex.Replace(calculationName, @"[\\\/:\*\?""'<>|.]", "_"); + } + + /// + /// + /// + /// + /// + /// + /// +// public void Calculate(Scenario scenario, SoilProfile1D soilProfile, string soilGeometry2DName, +// int iterationIndex) +// { +// Calculate(scenario, soilProfile, soilGeometry2DName, iterationIndex, null); +// } + + /// + /// Calculate 1 scenario + /// + /// + /// + /// + /// +// public void Calculate(Scenario scenario, SoilProfile1D soilProfile, string soilGeometry2DName, +// int iterationIndex, MStabDesignEmbankment mstabDesignEmbankment) +// { +// failureMechanismeParamatersMStab.MStabParameters.IsProbabilistic = ((this.ProbabilisticType == +// ProbabilisticType.Probabilistic) || +// (this.ProbabilisticType == +// ProbabilisticType +// .ProbabilisticFragility)); +// string soilGeometryName; +// if (!string.IsNullOrEmpty(soilGeometry2DName)) +// { +// soilGeometryName = Path.GetFileName(soilGeometry2DName); +// } +// else +// { +// soilGeometryName = soilProfile.Name; +// } +// +// string calculationName = DetermineCalculationFilename(scenario.Location.Name, scenario.LocationScenarioID, +// soilGeometryName, iterationIndex); +// +// try +// { +// StabilityServiceAgent stabilityServiceAgent = new StabilityServiceAgent(); +// stabilityServiceAgent.ProgramType = this.programType; +// stabilityServiceAgent.SlopeWExePath = this.slopeWProgramPath; +// stabilityServiceAgent.MStabExePath = this.mstabProgramPath; +// string stabilityDirectory = GetStabilityCalculationDirectory(); +// string filenameExtension = GetFilenameExtension(); +// string fileName = calculationName + filenameExtension; +// stabilityProjectFilename = Path.Combine(stabilityDirectory, fileName); +// +// MStabResults mStabResults = new MStabResults(); +// mStabResults.Init(); +// switch (ProbabilisticType) +// { +// case ProbabilisticType.Deterministic: +// { +// CalculateType(stabilityProjectFilename, scenario, soilProfile, soilGeometry2DName, +// stabilityServiceAgent, scenario.RiverLevel, mstabDesignEmbankment); +// scenario.SetFailureProbabilityStability(soilProfile, Path.GetFileName(soilGeometry2DName), null); +// break; +// } +// case ProbabilisticType.Probabilistic: +// { +// CalculateType(stabilityProjectFilename, scenario, soilProfile, soilGeometry2DName, +// stabilityServiceAgent, scenario.RiverLevel, mstabDesignEmbankment); +// double beta = 0; +// beta = stabilityServiceAgent.ExtractBeta(stabilityProjectFilename); +// scenario.SetFailureProbabilityStability(soilProfile, soilGeometry2DName, +// Probabilistic.Probabilistic.NormalDistribution(-beta)); +// break; +// } +// case ProbabilisticType.ProbabilisticFragility: +// { +// double[] waterLevels = scenario.DetermineProperWaterlevelsForProbabilisticAdvanced(); +// double[] betas = new double[3]; +// for (int i = 0; i < 3; i++) +// { +// string fileNameAdvanced = calculationName + "_WL" + i + ".sti"; +// stabilityProjectFilename = Path.Combine(stabilityDirectory, fileNameAdvanced); +// CalculateType(stabilityProjectFilename, scenario, soilProfile, soilGeometry2DName, +// stabilityServiceAgent, waterLevels[i], mstabDesignEmbankment); +// betas[i] = stabilityServiceAgent.ExtractBeta(stabilityProjectFilename); +// } +// var designPointWater = new DesignPointCalculation(); +// designPointWater.Waterlevels = waterLevels; +// designPointWater.Betas = betas; +// // Note Bka: For now, set MHW to original max water level (= river level + WaterHeightDecimeringsHoogte) and set +// // Decimate to the original WaterHeightDecimeringsHoogte. Han Best has to approve this! +// designPointWater.MHW = (double)(scenario.RiverLevel + scenario.WaterHeightDecimeringsHoogte); +// designPointWater.Decimate = (double)scenario.WaterHeightDecimeringsHoogte; +// designPointWater.Exceed = DesignPointCalculation.ExceedingSet.twoThousend; +// designPointWater.IsMaxLevelUsed = false; +// designPointWater.MaxLevel = 0; +// +// if (designPointWater.CalculateTheWaterDesignpoint()) +// { +// scenario.SetFailureProbabilityStability(soilProfile, soilGeometry2DName, +// Probabilistic.Probabilistic.NormalDistribution(-designPointWater.Beta)); +// } +// break; +// } +// } +// if (SelectedStabilityKernelType == StabilityKernelType.DamClassic) +// { +// mStabResults = stabilityServiceAgent.ExtractStabilityResults(stabilityProjectFilename); +// mStabResults = SetMStabAdministrationResults(mStabResults, iterationIndex, calculationName); +// DetermineMStabResultsEntryPoint(ref mStabResults, +// failureMechanismeParamatersMStab.MStabParameters.GridPosition); +// DetermineMStabResultsExitPoint(ref mStabResults, +// failureMechanismeParamatersMStab.MStabParameters.GridPosition); +// scenario.SetMStabResults(soilProfile, Path.GetFileName(soilGeometry2DName), mStabResults); +// } +// else +// { +// if (dotNetMstabProjectResults != null) +// { +// string stabilityResultsFileName = stabilityProjectFilename.Replace("sti", "dsx"); +// if (File.Exists(stabilityResultsFileName)) +// { +// File.Delete(stabilityResultsFileName); +// } +// var filledGeometry = dotNetMstabProjectResults.Geometry; +// // Todo het juist vullen van het Mstab project met alle waarden op de benodige plek (iom Rob) dus ook de results +// SaveStabilityProjectToDsxFile(stabilityResultsFileName, dotNetMstabProjectResults); +// mStabResults = ExtractDotNetStabilityKernelResults(); +// mStabResults = SetMStabAdministrationResults(mStabResults, iterationIndex, calculationName); +// if (dotNetMstabProjectResults.Stability.MinimumSafetyCurve == null && +// !IsSlidingDataMinimumSafetyCurveAvailable()) +// { +// return; +// } +// var cn = Path.GetFileNameWithoutExtension(stabilityResultsFileName); +// mStabResults.CalculationName = cn; +// DetermineDotNetStabilityKernelResultsEntryPoint(mStabResults); +// // TODO: Exit point is not read correctly +// DetermineDotNetStabilityKernelResultsExitPoint(mStabResults); +// scenario.SetMStabResults(soilProfile, Path.GetFileName(soilGeometry2DName), mStabResults); +// } +// } +// } +// +// catch (Exception e) +// { +// throw new DamFailureMechanismeCalculatorException( +// String.Format("Error calculating stability factor for '{0}'", calculationName), e); +// } +// } + + private static MStabResults SetMStabAdministrationResults(MStabResults mStabResults, int iterationIndex, + string calculationName) + { + mStabResults.CalculationName = calculationName; + mStabResults.CalculationSubDir = StabilitySubDir; + mStabResults.IterationNumber = iterationIndex; + if (StabilityCalculator.ModelSubDirectory != "") + { + mStabResults.CalculationSubDir = Path.Combine(mStabResults.CalculationSubDir, + StabilityCalculator.ModelSubDirectory); + } + return mStabResults; + } + + +// private bool IsSlidingDataMinimumSafetyCurveAvailable() +// { +// var notAvailable = dotNetMstabProjectResults.SlidingData == null || +// dotNetMstabProjectResults.SlidingData.CurrentZone == null || +// dotNetMstabProjectResults.SlidingData.CurrentZone.MinimumSafetyCurve == null; +// return !notAvailable; +// } + +// private MStabResults ExtractDotNetStabilityKernelResults() +// { +// MStabResults mStabResults = new MStabResults(); +// if (dotNetMstabProjectResults.Stability.HasZonePlot) +// { +// throw new NotImplementedException("Zoning features are not implementen yet in the Wti Stability kernel"); +// } +// else +// { +// if (dotNetMstabProjectResults.Stability.MinimumSafetyCurve == null) +// { +// if (!IsSlidingDataMinimumSafetyCurveAvailable()) +// { +// return mStabResults; +// } +// else +// { +// dotNetMstabProjectResults.Stability.MinimumSafetyCurve = +// dotNetMstabProjectResults.SlidingData.CurrentZone.MinimumSafetyCurve; +// } +// } +// double safetyFactor = dotNetMstabProjectResults.Stability.MinimumSafetyCurve.SafetyFactor; +// mStabResults.zone1.safetyFactor = safetyFactor; +// mStabResults.zone1.circleSurfacePointLeftXCoordinate = dotNetMstabProjectResults.Stability.MinimumSafetyCurve.LeftPoint.X; +// mStabResults.zone1.circleSurfacePointRightXCoordinate = dotNetMstabProjectResults.Stability.MinimumSafetyCurve.RightPoint.X; +// if (dotNetMstabProjectResults.Stability.ModelOption == ModelOptions.UpliftVan || +// dotNetMstabProjectResults.Stability.ModelOption == ModelOptions.UpliftSpencer) +// { +// mStabResults.zone1.safetyFactor = safetyFactor / 1.05; +// } +// } +// return mStabResults; +// } + +// private void DetermineDotNetStabilityKernelResultsExitPoint(MStabResults results) +// { +// if (dotNetMstabProjectResults.Stability.GridOrientation == GridOrientation.Outwards) +// { +// if (dotNetMstabProjectResults.Stability.MinimumSafetyCurve.LeftPoint != null) +// { +// // Outward stability +// results.zone1.exitPointXCoordinate = dotNetMstabProjectResults.Stability.MinimumSafetyCurve.LeftPoint.X; +// if (results.zone2.HasValue) +// { +// } +// } +// } +// else +// { +// // Inward stability +// if (dotNetMstabProjectResults.Stability.MinimumSafetyCurve.RightPoint != null) +// { +// results.zone1.exitPointXCoordinate = dotNetMstabProjectResults.Stability.MinimumSafetyCurve.RightPoint.X; +// if (results.zone2.HasValue) +// { +// } +// } +// } +// } + +// private void DetermineDotNetStabilityKernelResultsEntryPoint(MStabResults mStabResults) +// { +// if (dotNetMstabProjectResults.Stability.GridOrientation == GridOrientation.Outwards) +// { +// if (dotNetMstabProjectResults.Stability.MinimumSafetyCurve.RightPoint != null) +// { +// mStabResults.zone1.entryPointXCoordinate = +// dotNetMstabProjectResults.Stability.MinimumSafetyCurve.RightPoint.X; +// if (mStabResults.zone2.HasValue) +// { +// /*MStabResultsSingleZone zone = mstabResults.zone2.Value; +// zone.entryPointXCoordinate = zone.circleSurfacePointRightXCoordinate; +// mstabResults.zone2 = zone;*/ +// } +// } +// } +// else +// { +// if (dotNetMstabProjectResults.Stability.MinimumSafetyCurve.LeftPoint != null) +// { +// // Inward stability +// mStabResults.zone1.entryPointXCoordinate = +// dotNetMstabProjectResults.Stability.MinimumSafetyCurve.LeftPoint.X; +// if (mStabResults.zone2.HasValue) +// { +// /*MStabResultsSingleZone zone = mstabResults.zone2.Value; +// zone.entryPointXCoordinate = zone.circleSurfacePointLeftXCoordinate; +// mstabResults.zone2 = zone;*/ +// } +// } +// } +// } + + /// + /// Determine filename extension according to which failuremechanism is used + /// + /// + public string GetFilenameExtension() + { + string filenameExtension; + if (programType == ProgramType.SlopeW) + { + filenameExtension = ".xml"; + } + else + { + filenameExtension = ".sti"; + } + return filenameExtension; + } + + /// + /// Depending on outward/inward stability (position of grid) the entrypoint of the slipcricle is determined + /// + /// + /// + private void DetermineMStabResultsEntryPoint(ref MStabResults mstabResults, MStabGridPosition mstabGridPosition) + { + if (mstabGridPosition == MStabGridPosition.Left) + { + // Outward stability + mstabResults.zone1.entryPointXCoordinate = mstabResults.zone1.circleSurfacePointRightXCoordinate; + if (mstabResults.zone2.HasValue) + { + MStabResultsSingleZone zone = mstabResults.zone2.Value; + zone.entryPointXCoordinate = zone.circleSurfacePointRightXCoordinate; + mstabResults.zone2 = zone; + } + } + else + { + // Inward stability + mstabResults.zone1.entryPointXCoordinate = mstabResults.zone1.circleSurfacePointLeftXCoordinate; + if (mstabResults.zone2.HasValue) + { + MStabResultsSingleZone zone = mstabResults.zone2.Value; + zone.entryPointXCoordinate = zone.circleSurfacePointLeftXCoordinate; + mstabResults.zone2 = zone; + } + } + } + + + /// + /// Depending on outward/inward stability (position of grid) the exitpoint of the slipcricle is determined + /// + /// + /// + private void DetermineMStabResultsExitPoint(ref MStabResults mstabResults, MStabGridPosition mstabGridPosition) + { + if (mstabGridPosition == MStabGridPosition.Left) + { + // Outward stability + mstabResults.zone1.exitPointXCoordinate = mstabResults.zone1.circleSurfacePointLeftXCoordinate; + if (mstabResults.zone2.HasValue) + { + MStabResultsSingleZone zone = mstabResults.zone2.Value; + zone.exitPointXCoordinate = zone.circleSurfacePointLeftXCoordinate; + mstabResults.zone2 = zone; + } + } + else + { + // Inward stability + mstabResults.zone1.exitPointXCoordinate = mstabResults.zone1.circleSurfacePointRightXCoordinate; + if (mstabResults.zone2.HasValue) + { + MStabResultsSingleZone zone = mstabResults.zone2.Value; + zone.exitPointXCoordinate = zone.circleSurfacePointRightXCoordinate; + mstabResults.zone2 = zone; + } + } + } + + private void CreateForbiddenZone(Scenario scenario, SurfaceLine2 surfaceLine) + { + var dikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); + // Zonestype is ForbiddenZone; TODO: Combine with code in StabilityCalculator? + double maxZoneX = dikeTopAtPolder.X + + scenario.Location.ForbiddenZoneFactor * (surfaceLine.GetDikeToeInward().X - dikeTopAtPolder.X); + failureMechanismeParamatersMStab.MStabParameters.ForbiddenZone = new MStabForbiddenZone + { + IsXEntryMinUsed = false, + XEntryMin = 0.0, + IsXEntryMaxUsed = true, + XEntryMax = maxZoneX + }; + } + + /// + /// Create XML definition for Stability calculation + /// + /// + /// + /// + /// + /// + /// + /// + /// +// public XDocument CreateMStabXmlDoc(string mstabProjectFilename, Scenario scenario, SoilProfile soilProfile, +// string soilGeometry2DName, double riverLevel, +// MStabDesignEmbankment mstabDesignEmbankment, SurfaceLine2 surfaceLine) +// { +// SoilProfile1D profile1D = soilProfile as SoilProfile1D; +// SoilProfile2D profile2D = soilProfile as SoilProfile2D; +// ConsistencyCheck(scenario, profile1D, soilGeometry2DName); +// failureMechanismeParamatersMStab.Location = scenario.Location; +// if (profile1D != null) +// { +// failureMechanismeParamatersMStab.SoilProfile = profile1D; +// // 1d-geometry +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.SoilGeometryType = +// SoilGeometryType.SoilGeometry1D; +// } +// else +// { +// // 2d-geometry +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.SoilGeometryType = +// SoilGeometryType.SoilGeometry2D; +// } +// // Geometry Creation Options +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.SoilGeometry2DFilename = +// soilGeometry2DName; +// +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.MaterialForDike = +// scenario.Location.DikeEmbankmentMaterial; +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.MaterialForShoulder = +// scenario.Location.ShoulderEmbankmentMaterial; +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.IsUseOriginalPLLineAssignments = +// scenario.Location.IsUseOriginalPLLineAssignments; +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.IsDesign = +// (mstabDesignEmbankment != null); +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.XOffsetSoilGeometry2DOrigin = +// -scenario.Location.XSoilGeometry2DOrigin; +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.PLLineAssignment = +// CalculationHelper.PLLineCreationMethod2PLLineAssignment(scenario.Location.PLLineCreationMethod); +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.IntrusionVerticalWaterPressureType = +// scenario.Location.IntrusionVerticalWaterPressure.Value; +// failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.PenetrationLength = +// scenario.Location.PenetrationLength; +// // End of Geometry Creation Options +// // Design options +// failureMechanismeParamatersMStab.Design = mstabDesignEmbankment; +// +// failureMechanismeParamatersMStab.SurfaceLine = surfaceLine; +// failureMechanismeParamatersMStab.RiverLevel = riverLevel; // scenario.RiverLevel; +// failureMechanismeParamatersMStab.DikeTableHeight = +// scenario.DikeTableHeight ?? surfaceLine.GetDefaultDikeTableHeight() ?? 0; +// failureMechanismeParamatersMStab.TrafficLoad = this.trafficLoad; +// +// // Horizontal balance; TODO: Combine with code in StabilityCalculation +// if (failureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.HorizontalBalance) +// { +// if (profile1D == null) +// { +// throw new DamFailureMechanismeCalculatorException( +// "Model horizontal balance does not support 2d-geometries"); +// } +// failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea = new HorizontalBalanceArea(); +// failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.XLeft = +// surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X; +// failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.XRight = +// surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; +// failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YTop = riverLevel; +// failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YBottom = +// profile1D.InBetweenAquiferLayer != null +// ? profile1D.InBetweenAquiferLayer.TopLevel +// : profile1D.BottomAquiferLayer.TopLevel; +// int planeCount = +// (int)(Math.Round((failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YTop - +// failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YBottom) / 0.25)); +// failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.PlaneCount = Math.Min(planeCount, 50); +// +// } +// +// // Zonestype is ZoneAreas; TODO: Combine with code in StabilityCalculation +// var dikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); +// if ( +// failureMechanismeParamatersMStab.MStabParameters.CalculationOptions.ZonesType.Equals( +// MStabZonesType.ZoneAreas)) +// { +// double? dikeTableHeight = scenario.DikeTableHeight ?? surfaceLine.GetDefaultDikeTableHeight() ?? null; +// if (!dikeTableHeight.HasValue) +// throw new DamFailureMechanismeCalculatorException("Surface line has no dike table height."); +// failureMechanismeParamatersMStab.MStabParameters.ZoneAreas = new MStabZoneAreas +// { +// DikeTableHeight = dikeTableHeight.Value, +// DikeTableWidth = scenario.Location.ZoneAreaRestSlopeCrestWidth, +// SafetyFactorZone1A = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? this.requiredSafetyFactor, +// SafetyFactorZone1B = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? this.requiredSafetyFactor, +// XCoordinateDikeTopAtPolder = dikeTopAtPolder.X, +// XCoordinateDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X, +// XCoordinateStartRestProfile = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X +// }; +// } +// +// if (failureMechanismeParamatersMStab.MStabParameters.CalculationOptions.ZonesType.Equals( +// MStabZonesType.ForbiddenZone)) +// { +// CreateForbiddenZone(scenario, surfaceLine); +// } +// +// // Make sure riverlevel is correct with respect to surfaceline +// double riverLevelLow = double.NaN; +// if (failureMechanismeParamatersMStab.MStabParameters.GridPosition == MStabGridPosition.Left && scenario.RiverLevelLow.HasValue) +// { +// riverLevelLow = scenario.RiverLevelLow.Value; +// } +// double? riverLevelHigh = riverLevel; +// var surfaceLevelOutside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside); +// if (riverLevelHigh < surfaceLevelOutside.Z) +// { +// var riverLevelHighIsBelowSurfaceLevelOutside = Path.GetFileName(mstabProjectFilename) + ": " + +// LocalizationManager.GetTranslatedText(this.GetType(), +// "riverLevelHighIsBelowSurfaceLevelOutside"); +// LogMessage logMessage = new LogMessage(LogMessageType.Warning, null, +// String.Format(riverLevelHighIsBelowSurfaceLevelOutside, riverLevelHigh, +// surfaceLevelOutside.Z)); +// errorMessages.Add(logMessage); +// } +// +// var currentSurfaceLine = scenario.GetMostRecentSurfaceLine(soilProfile, Path.GetFileName(soilGeometry2DName)); +// if (currentSurfaceLine == null) +// { +// currentSurfaceLine = surfaceLine; +// } +// if (SelectedStabilityKernelType == StabilityKernelType.AdvancedWti || +// SelectedStabilityKernelType == StabilityKernelType.AdvancedDotNet) +// { +// var lphreaticAdaptionType = NWOPhreaticAdaption != null +// ? (PhreaticAdaptionType)NWOPhreaticAdaption +// : PhreaticAdaptionType.None; +// var stabilityProjectObjectCreator = new StabilityProjectObjectCreator(); +// failureMechanismeParamatersMStab.PLLines = stabilityProjectObjectCreator.CreateAllPlLinesUsingWaternetCreator(scenario.Location, +// currentSurfaceLine, soilProfile, lphreaticAdaptionType, modelParametersForPLLines.PenetrationLength, riverLevelHigh.Value, modelParametersForPLLines.PLLineCreationMethod, riverLevelLow); +// } +// else +// { +// failureMechanismeParamatersMStab.PLLines = CreateAllPLLines(scenario.Location, currentSurfaceLine, +// soilProfile, soilGeometry2DName, riverLevelHigh.Value, riverLevelLow); +// } +// // Slip circle definition for Uplift Van; TODO: Combine with code in StabilityCalculation +// if (this.failureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.UpliftVan) +// { +// // Determine right side of slip plane grid (right grid) +// // This is the location with the lowest uplift factor or, if present, the second NWO point +// var upliftLocationAndResult = this.GetLocationWithLowestUpliftFactor(currentSurfaceLine, soilProfile, +// soilGeometry2DName, +// failureMechanismeParamatersMStab.PLLines, +// scenario.Location); +// double upliftCriterion = +// scenario.GetUpliftCriterionStability(scenario.Location.ModelFactors.UpliftCriterionStability); +// bool isUplift = !(upliftLocationAndResult == null) && +// (upliftLocationAndResult.UpliftFactor < upliftCriterion); +// double xCoordinateLastUpliftPoint = isUplift +// ? upliftLocationAndResult.X +// : currentSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; +// var nonWaterRetaining2 = currentSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint2); +// if (nonWaterRetaining2 != +// null) +// { +// xCoordinateLastUpliftPoint = +// nonWaterRetaining2.X; +// } +// failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.XCoordinateLastUpliftPoint = +// xCoordinateLastUpliftPoint; +// } +// +// failureMechanismeParamatersMStab.MStabParameters.ProjectFileName = mstabProjectFilename; +// failureMechanismeParamatersMStab.MStabParameters.SoilDatabaseName = scenario.Location.SoildatabaseName; +// +// if (!failureMechanismeParamatersMStab.IsComplete) +// { +// throw new Exception("Not all required data is available"); +// } +// DamMStabAssembler assembler = new DamMStabAssembler(); +// XDocument mstabXML = assembler.CreateDataTransferObject(failureMechanismeParamatersMStab); +// return mstabXML; +// } + + /// + /// Determines which MStabResults of 2, contains the smallest safety factor + /// + /// + /// + /// MStab results with the minimum safety factor + public static MStabResults MinMStabResults(MStabResults mStabResults1, MStabResults mStabResults2) + { + if (mStabResults2.zone1.safetyFactor < mStabResults1.zone1.safetyFactor) + { + return mStabResults2; + } + else + { + return mStabResults1; + } + } + + /// + /// This is the place where we determine where the DGeoStability executable is located + /// + public static string MStabExePath + { + get + { + return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + @"DGeoStability.exe"); + } + } + + public string StabilityProjectFilename + { + get { return stabilityProjectFilename; } + } + + public List ErrorMessages + { + get { return errorMessages; } + set { errorMessages = value; } + } + + // option of various computation kernel types + public StabilityKernelType SelectedStabilityKernelType { get; set; } + + /// + /// save stability project to dsx file + /// + /// + /// +// public void SaveStabilityProjectToDsxFile(string fileName, MStabProject project) +// { +// DataEventPublisher.InvokeWithoutPublishingEvents(() => +// { +// var xmlSerializer = new XmlSerializer(); +// xmlSerializer.Serialize(project, fileName, AppDomain.CurrentDomain.BaseDirectory + "Mstab.xsl"); +// }); +// } + +// private string SaveStabilityProjectFileToString(object stabilityProject) +// { +// var xmlSerializer = new XmlSerializer(); +// return xmlSerializer.SerializeToString(stabilityProject); +// } + + /// + /// Gets the location with lowest uplift factor. + /// + /// The surface line. + /// The soil profile. + /// Name of the soil geometry2 D. + /// The pl lines. + /// The location. + /// + public UpliftLocationAndResult GetLocationWithLowestUpliftFactor(SurfaceLine2 surfaceLine, + SoilProfile soilProfile, string soilGeometry2DName, PLLines plLines, Location location) + { + var profile1D = soilProfile as SoilProfile1D; + var profile2D = soilProfile as SoilProfile2D; + UpliftLocationDeterminator upliftLocationDeterminator = new UpliftLocationDeterminator() + { + SurfaceLine = surfaceLine, + SoilProfile = profile1D, + SoilProfile2D = profile2D, + SoilGeometry2DName = soilGeometry2DName, + SoilList = location.SoilList, + DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), + PLLines = plLines, + XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin + }; + return upliftLocationDeterminator.GetLocationAtWithLowestUpliftFactor(); + } + + public void Dispose() + { + if (dotNetMstabProjectResults != null) + { + dotNetMstabProjectResults.Dispose(); + } + } + } +} Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenariosResult.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenariosResult.cs (.../RWScenariosResult.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenariosResult.cs (.../RWScenariosResult.cs) (revision 330) @@ -135,26 +135,17 @@ { } - [Browsable(false)] - [Label("Location")] public virtual Location Location { get { return location; } set { location = value; } } - [Label("Location")] - [PropertyOrder(0, 1)] public string LocationName { get { return this.Location.Name; } } - [ReadOnly(true)] - [Format("F3")] - [Label("Detriment factor")] - [Category(ResultCategory)] - [PropertyOrder(2, 1)] public double DetrimentFactor { get @@ -166,9 +157,6 @@ } } - [Label("Soil profile")] - [Category(CalculationCategory)] - [PropertyOrder(2, 2)] public string SoilProfileName { get @@ -180,11 +168,6 @@ } } - [ReadOnly(true)] - [Format("F3")] - [Label("Soil profile probability")] - [Category(CalculationCategory)] - [PropertyOrder(2, 3)] public double SoilProfileProbability { get @@ -196,103 +179,67 @@ } } - [ReadOnly(true)] - [Label("Load situation")] - [Category(CalculationCategory)] - [PropertyOrder(2, 4)] public LoadSituation LoadSituation { get { return loadSituation; } set { loadSituation = value; } } - [ReadOnly(true)] - [Label("Dry sensitivity")] - [Category(CalculationCategory)] - [PropertyOrder(2, 5)] public DikeDrySensitivity DikeDrySensitivity { get { return _dikeDrySensitivity; } set { _dikeDrySensitivity = value; } } - [ReadOnly(true)] - [Label("Hydraulic shortcut")] - [Category(CalculationCategory)] - [PropertyOrder(2, 6)] public HydraulicShortcutType HydraulicShortcutType { get { return hydraulicShortcutType; } set { hydraulicShortcutType = value; } } - [ReadOnly(true)] - [Label("Uplift type")] - [Category(CalculationCategory)] - [PropertyOrder(2, 7)] public UpliftType UpliftType { get { return upliftType; } set { upliftType = value; } } - [ReadOnly(true)] - [Label("Model Stability")] - [Category(CalculationCategory)] - [PropertyOrder(2, 8)] - [XmlOldName("ModelOption")] public MStabModelType MstabModelOption { get { return mstabModelOption; } set { mstabModelOption = value; } } - [ReadOnly(true)] - [Label("Model Piping")] - [Category(CalculationCategory)] - [PropertyOrder(2, 8)] public PipingModelType PipingModelOption { get { return pipingModelOption; } set { pipingModelOption = value; } } - [Browsable(false)] - [Category(CalculationCategory)] public MStabParameters MStabParameters { get; set; } - [ReadOnly(true)] - [Label("Scenario")] - [PropertyOrder(0, 2)] public ScenarioType ScenarioType { get { return scenarioType; } set { scenarioType = value; } } - [Browsable(false)] - [Label("File name")] public string BaseFileName { get { return baseFileName; } set { baseFileName = value; } } - [Browsable(false)] - [Label("Input file")] public string InputFile { - get { return DamProject.ProjectWorkingPath + Path.DirectorySeparatorChar + baseFileName + ".sti"; } + get { return DamProjectData.ProjectWorkingPath + Path.DirectorySeparatorChar + baseFileName + ".sti"; } } - [Browsable(false)] - [Label("Image file")] public string ResultFile { get { const string wmfExtension = ".wmf"; - string fullBaseFilename = DamProject.ProjectWorkingPath + Path.DirectorySeparatorChar + baseFileName; + string fullBaseFilename = DamProjectData.ProjectWorkingPath + Path.DirectorySeparatorChar + baseFileName; string fullFilename = fullBaseFilename + wmfExtension; if (!File.Exists(fullFilename)) { @@ -306,23 +253,22 @@ } } - [Browsable(false)] - [Label("Input file")] public string PipingResultFile { + get + { + return "leeg"; + } // Note Bka: Path of piping is not based on the working dir but on assembly (Assembly.GetExecutingAssembly().Location) - get { return baseFileName + PipingCalculator.PipingFilenameExtension; } + // get { return baseFileName + PipingCalculator.PipingFilenameExtension; } ##Bka: most probably unwanted, replace with other mechanism. Or delete when NOT USED } - [Label("Failure mechanism")] public FailureMechanismSystemType FailureMechanismType { get { return failureMechanismType; } set { failureMechanismType = value; } } - [Browsable(false)] - [Label("Soil geometry")] public SoilGeometryProbability SoilGeometryProbability { get { return soilGeometryProbability; } Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/PlLines/PL1Line.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/PlLines/PL1Line.cs (.../PL1Line.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/PlLines/PL1Line.cs (.../PL1Line.cs) (revision 330) @@ -44,7 +44,7 @@ } } - public PL1Line Clone() + public new PL1Line Clone() { var newPL1Line = new PL1Line(); Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs (.../SoilLayer1D.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs (.../SoilLayer1D.cs) (revision 330) @@ -170,7 +170,7 @@ /// Assigns the specified layer. /// /// The layer. - private void Assign(SoilLayer1D layer) + public void Assign(SoilLayer1D layer) { Name = layer.Name; TopLevel = layer.TopLevel; Fisheye: Tag 330 refers to a dead (removed) revision in file `dam engine/branches/Initial Source/Deltares.DamEngine.Controllers/StabilityServiceAgentException.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamRunner.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamRunner.cs (.../DamRunner.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamRunner.cs (.../DamRunner.cs) (revision 330) @@ -26,10 +26,13 @@ using System.Reflection; using System.Text; using Deltares.DamEngine.Calculators.Dikes_Assessment; +using Deltares.DamEngine.Calculators.Stability; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.RWScenarios; using Deltares.DamEngine.Data.Standard.Calculation; +using Deltares.DamEngine.Data.Standard.Language; +using Deltares.DamEngine.Data.Standard.Logging; namespace Deltares.DamEngine.Calculators { @@ -42,7 +45,7 @@ public DamRunner(DamProjectData damProjectData, string projectFileName) { - damProjectData = damProjectData; + this.damProjectData = damProjectData; directory = Path.GetDirectoryName(projectFileName); } @@ -58,29 +61,29 @@ string paragraphSepatator = Environment.NewLine + Environment.NewLine; if (output.StartsWith("Thread was being aborted")) { - LocalizedMessageBox.Show(this, "CalculationAborted"); + // LocalizedMessageBox.Show(this, "CalculationAborted"); ##Bka: most probably unwanted, replace with other mechanism } else if (result == CalculationResult.Succeeded) { string openingMessage = LocalizationManager.GetTranslatedText(this, "CalculationFinished"); - LocalizedMessageBox.ShowTranslatedText(openingMessage + paragraphSepatator + timeMessage + paragraphSepatator + output); + // LocalizedMessageBox.ShowTranslatedText(openingMessage + paragraphSepatator + timeMessage + paragraphSepatator + output); ##Bka: most probably unwanted, replace with other mechanism } else if ((result == CalculationResult.RunFailed) || (result == CalculationResult.UnexpectedError)) { string openingMessage = LocalizationManager.GetTranslatedText(this, "CalculationFailed"); - LocalizedMessageBox.ShowTranslatedText(openingMessage + paragraphSepatator + output); - } + //LocalizedMessageBox.ShowTranslatedText(openingMessage + paragraphSepatator + output); ##Bka: most probably unwanted, replace with other mechanism + } } private void ProcessResult(DamProjectData damProject, CalculationResult result, string output) { - if (BindSupport.InvokeControl.InvokeRequired) + // if (BindSupport.InvokeControl.InvokeRequired) + // { + // var d = new ProcessResultDelegate(ProcessResultLocal); + // BindSupport.InvokeControl.Invoke(d, new object[] { damProject, result, output }); + // } + // else ##Bka: most probably unwanted, replace with other mechanism { - var d = new ProcessResultDelegate(ProcessResultLocal); - BindSupport.InvokeControl.Invoke(d, new object[] { damProject, result, output }); - } - else - { ProcessResultLocal(damProject, result, output); } } @@ -102,7 +105,7 @@ damCalculation.ProjectDataDirectory = directory + Path.DirectorySeparatorChar; damCalculation.MStabExePath = StabilityCalculator.MStabExePath; damCalculation.MaxCalculationCores = MaxCalculationCores; - damCalculation.CalculateDamProject(damProjectData); + damCalculation.CalculateDamProject(damProjectData, DamProjectData.ProjectWorkingPath); //##Bka!? or damCalculation.ProjectDataDirectory var output = FillOutputForMessage(damProjectData.LocationJobs); ProcessResult(damProjectData, CalculationResult.Succeeded, output); break; @@ -128,9 +131,9 @@ CalculationResult calculationResult; try { - rwScenariosCalculation.Load(evaluationJob.XML); + //rwScenariosCalculation.Load(evaluationJob.XML); ##Bka calculationResult = rwScenariosCalculation.Run(); - DataEventPublisher.DataListModified(LogManager.Messages); + //DataEventPublisher.DataListModified(LogManager.Messages); } catch (Exception) { @@ -140,7 +143,7 @@ string results = ""; rwScenariosCalculation.GetResults(ref results); - evaluationJob.XML = results; + //evaluationJob.XML = results; ##Bka evaluationJob.AttachResults(damProjectData.LocationJobs); var output = FillOutputForMessage(damProjectData.LocationJobs); ProcessResult(damProjectData, calculationResult, output); @@ -158,7 +161,7 @@ SlopeWProgramPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Slope2.exe"), ProjectDataDirectory = directory + Path.DirectorySeparatorChar, Progress = progressDelegate, - CalculationBaseDirectory = DamProject.ProjectWorkingPath + @"\CalculationFiles\" + CalculationBaseDirectory = DamProjectData.ProjectWorkingPath + @"\CalculationFiles\" }; damProjectCalculator.Calculate(damProjectData, scenarios); @@ -229,27 +232,27 @@ private void RemoveLogMessages(EvaluationJob evaluationJob) { - foreach (LogMessage logMessage in LogManager.Messages.ToArray()) - { - foreach (var location in evaluationJob.Locations) - { - if (logMessage.SubjectName.Equals(location.ToString())) - { - LogManager.Messages.Remove(logMessage); - } - } - } - - DataEventPublisher.DataListModified(LogManager.Messages); +// foreach (LogMessage logMessage in LogManager.Messages.ToArray()) +// { +// foreach (var location in evaluationJob.Locations) +// { +// if (logMessage.SubjectName.Equals(location.ToString())) +// { +// LogManager.Messages.Remove(logMessage); +// } +// } +// } +// +// DataEventPublisher.DataListModified(LogManager.Messages); } private void HandleCalculationSendMessage(LogMessage logMessage) { - lock (LogManager.Messages) - { - LogManager.Messages.Add(logMessage); - DataEventPublisher.DataListModified(LogManager.Messages); - } +// lock (LogManager.Messages) +// { +// LogManager.Messages.Add(logMessage); +// DataEventPublisher.DataListModified(LogManager.Messages); +// } } public int MaxCalculationCores Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenariosCalculation.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenariosCalculation.cs (.../Dikes Assessment/RWScenariosCalculation.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenariosCalculation.cs (.../Dikes Assessment Regional/RWScenariosCalculation.cs) (revision 330) @@ -23,10 +23,20 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Xml.Serialization; +using Deltares.DamEngine.Calculators.SchematizationFactor; using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.General.Results; +using Deltares.DamEngine.Data.General.SchematizationFactor; +using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.RWScenarios; using Deltares.DamEngine.Data.Standard.Calculation; +using Deltares.DamEngine.Data.Standard.Language; +using Deltares.DamEngine.Data.Standard.Logging; +using RWScenarioSelector = Deltares.DamEngine.Calculators.Dikes_Assessment_Regional.RWScenarioSelector; namespace Deltares.DamEngine.Calculators.Dikes_Assessment { @@ -63,30 +73,32 @@ public CalculationResult GetResults(ref string results) { - try - { - XmlSerializer serializer = new XmlSerializer(); - results = serializer.SerializeToString(this.evaluationJob); - return CalculationResult.Succeeded; - } - catch - { - return CalculationResult.UnexpectedError; - } + // try + // { + // XmlSerializer serializer = new XmlSerializer(); + // results = serializer.SerializeToString(this.evaluationJob); + // return CalculationResult.Succeeded; + // } + // catch + // { + // return CalculationResult.UnexpectedError; + // }##Bka + return CalculationResult.UnexpectedError; } public CalculationResult Load(string input) { - try - { - XmlDeserializer deserializer = new XmlDeserializer(); - this.evaluationJob = (EvaluationJob)deserializer.XmlDeserializeFromString(input, typeof(EvaluationJob), new DefaultClassFactory()); - return CalculationResult.Succeeded; - } - catch - { - return CalculationResult.UnexpectedError; - } + // try + // { + // XmlDeserializer deserializer = new XmlDeserializer(); + // this.evaluationJob = (EvaluationJob)deserializer.XmlDeserializeFromString(input, typeof(EvaluationJob), new DefaultClassFactory()); + // return CalculationResult.Succeeded; + // } + // catch + // { + // return CalculationResult.UnexpectedError; + // }##Bka + return CalculationResult.UnexpectedError; } public CalculationResult RegisterGetValues(GetValuesDelegate getValuesDelegate) @@ -129,14 +141,14 @@ List tasks = this.FillQueue(); - Parallel.Run(tasks, this.RunTask, this.progressDelegate, this.MaxCalculationCores); + General.Parallel.Run(tasks, this.RunTask, this.progressDelegate, this.MaxCalculationCores); this.FillResults(tasks); return CalculationResult.Succeeded; } catch(Exception exception) { - sendMessageDelegate(new LogMessage(LogMessageType.Warning, null, "Unexpected error:", exception.Message)); + sendMessageDelegate(new LogMessage(LogMessageType.Warning, null, "Unexpected error:" + exception.Message)); throw exception; } } @@ -206,7 +218,7 @@ { this.evaluationJob.FailedEvaluatedLocations.Add(location); sendMessageDelegate( - new LogMessage(LogMessageType.Warning, location, String.Format("Location has no soilprofiles"), + new LogMessage(LogMessageType.Warning, location, String.Format("Location has no soilprofiles: ") + String.Format("Segment: {0}", location.Segment.Name))); } @@ -217,7 +229,7 @@ if (soilGeometryProbability.SoilGeometryType == SoilGeometryType.SoilGeometry2D) { this.evaluationJob.FailedEvaluatedLocations.Add(location); - sendMessageDelegate(new LogMessage(LogMessageType.Warning, location, LocalizationManager.GetTranslatedText(this, "Geometry2DNotSupportedInRegionalAssessment"), + sendMessageDelegate(new LogMessage(LogMessageType.Warning, location, LocalizationManager.GetTranslatedText(this, "Geometry2DNotSupportedInRegionalAssessment") + String.Format("Segment: {0}", location.Segment.Name))); } else @@ -237,7 +249,7 @@ { this.evaluationJob.FailedEvaluatedLocations.Add(location); sendMessageDelegate( - new LogMessage(LogMessageType.Warning, location, String.Format("Cannot generate scenarios: {0}", e.Message), + new LogMessage(LogMessageType.Warning, location, String.Format("Cannot generate scenarios: {0}", e.Message) + String.Format("Soilprofile: {0}", soilProfile.Name))); } } @@ -293,21 +305,18 @@ /// private void ProcessJob(RWScenarioProfileResult job) { - DataEventPublisher.InvokeWithoutPublishingEvents(() => + Debug.WriteLine(String.Format("Job {0}, location {1}, Scenario {2}", job.FailureMechanismType.ToString(), job.LocationName, job.ScenarioType.ToString())); + switch (job.FailureMechanismType) { - Debug.WriteLine(String.Format("Job {0}, location {1}, Scenario {2}", job.FailureMechanismType.ToString(), job.LocationName, job.ScenarioType.ToString())); - switch (job.FailureMechanismType) - { - case FailureMechanismSystemType.StabilityInside: - ProcessJobStability(job); - break; - case FailureMechanismSystemType.Piping: - ProcessJobPiping(job); - break; - default: - throw new RWScenariosCalculationException(String.Format("Failuremechanism {0} not yet implemented for scenario calculation", job.FailureMechanismType)); - } - }); + case FailureMechanismSystemType.StabilityInside: + ProcessJobStability(job); + break; + case FailureMechanismSystemType.Piping: + ProcessJobPiping(job); + break; + default: + throw new RWScenariosCalculationException(String.Format("Failuremechanism {0} not yet implemented for scenario calculation", job.FailureMechanismType)); + } } /// @@ -316,47 +325,47 @@ /// private void ProcessJobPiping(RWScenarioProfileResult job) { - if (job.Location.ModelFactors.UpliftCriterionPiping.HasValue) - { - var modelParametersForPLLines = new ModelParametersForPLLines(); - var calculator = GetCalculatorForPipingModel(job, modelParametersForPLLines); - double waterLevel; - switch (job.LoadSituation) - { - case LoadSituation.Dry: - waterLevel = job.Location.BoezemLevelLbp; - break; - default: // LoadSituation.Wet - waterLevel = job.Location.BoezemLevelTp; - break; - } - job.SoilGeometryProbability.SoilProfile.EnsureUniqueLayerIds(); - var calculationName = GetCalculationNameForPipingCalculator(job); - calculator.FilenameCalculation = Path.Combine(Path.Combine(DamProject.ProjectWorkingPath, job.FailureMechanismType.ToString()), calculationName); - calculator.IsHydraulicShortcut = (job.HydraulicShortcutType == HydraulicShortcutType.HydraulicShortcut); - double? pipingFactor = calculator.CalculatePipingFactor(job.Location, job.Location.LocalXZSurfaceLine2, job.SoilGeometryProbability.SoilProfile, waterLevel); - job.BaseFileName = calculator.FilenameCalculation; +// if (job.Location.ModelFactors.UpliftCriterionPiping.HasValue) +// { +// var modelParametersForPLLines = new ModelParametersForPLLines(); +// var calculator = GetCalculatorForPipingModel(job, modelParametersForPLLines); +// double waterLevel; +// switch (job.LoadSituation) +// { +// case LoadSituation.Dry: +// waterLevel = job.Location.BoezemLevelLbp; +// break; +// default: // LoadSituation.Wet +// waterLevel = job.Location.BoezemLevelTp; +// break; +// } +// job.SoilGeometryProbability.SoilProfile.EnsureUniqueLayerIds(); +// var calculationName = GetCalculationNameForPipingCalculator(job); +// calculator.FilenameCalculation = Path.Combine(Path.Combine(DamProject.ProjectWorkingPath, job.FailureMechanismType.ToString()), calculationName); +// calculator.IsHydraulicShortcut = (job.HydraulicShortcutType == HydraulicShortcutType.HydraulicShortcut); +// double? pipingFactor = calculator.CalculatePipingFactor(job.Location, job.Location.LocalXZSurfaceLine2, job.SoilGeometryProbability.SoilProfile, waterLevel); +// job.BaseFileName = calculator.FilenameCalculation; +// +// job.RwResultType = RWResultType.SafetyFactor; +// if (pipingFactor.HasValue) +// { +// job.SafetyFactor = pipingFactor.Value; +// job.CalculationResult = CalculationResult.Succeeded; +// job.ProbabilityOfFailure = double.NaN; +// job.RwResultType = RWResultType.SafetyFactor; +// } +// +// else +// { +// job.SafetyFactor = double.NaN; +// job.CalculationResult = CalculationResult.RunFailed; +// } +// } +// else +// { +// throw new RWScenariosCalculationException(String.Format("Uplift criterion not defined for location {0}", job.Location.Name)); +// } ##Bka - job.RwResultType = RWResultType.SafetyFactor; - if (pipingFactor.HasValue) - { - job.SafetyFactor = pipingFactor.Value; - job.CalculationResult = CalculationResult.Succeeded; - job.ProbabilityOfFailure = double.NaN; - job.RwResultType = RWResultType.SafetyFactor; - } - - else - { - job.SafetyFactor = double.NaN; - job.CalculationResult = CalculationResult.RunFailed; - } - } - else - { - throw new RWScenariosCalculationException(String.Format("Uplift criterion not defined for location {0}", job.Location.Name)); - } - } private string GetCalculationNameForPipingCalculator(RWScenarioProfileResult job) @@ -388,83 +397,83 @@ /// /// /// proper piping calculator - private PipingCalculator GetCalculatorForPipingModel(RWScenarioProfileResult job, ModelParametersForPLLines modelParametersForPLLines) - { - PipingCalculator calculator; - switch (job.PipingModelOption) - { - case PipingModelType.Sellmeijer: calculator = new PipingCalculatorSellmeijer(modelParametersForPLLines, - 1.0, null, null, null, job.Location.ModelFactors.UpliftCriterionPiping.Value); - break; - case PipingModelType.Sellmeijer2Forces: calculator = new PipingCalculatorSellmeijer2Forces(modelParametersForPLLines, - 1.0, null, null, job.Location.ModelFactors.UpliftCriterionPiping.Value); - break; - case PipingModelType.Sellmeijer4Forces: calculator = new PipingCalculatorSellmeijer4Forces(modelParametersForPLLines, - 1.0, null, null, job.Location.ModelFactors.UpliftCriterionPiping.Value); - break; - case PipingModelType.Bligh: calculator = new PipingCalculatorBligh(modelParametersForPLLines, - 1.0, null, null, job.Location.ModelFactors.UpliftCriterionPiping.Value); - break; - default: - throw new RWScenariosCalculationException(String.Format("Piping model {0} not yet implemented for scenario calculation", job.PipingModelOption)); - } - return calculator; - } +// private PipingCalculator GetCalculatorForPipingModel(RWScenarioProfileResult job, ModelParametersForPLLines modelParametersForPLLines) +// { +// PipingCalculator calculator; +// switch (job.PipingModelOption) +// { +// case PipingModelType.Sellmeijer: calculator = new PipingCalculatorSellmeijer(modelParametersForPLLines, +// 1.0, null, null, null, job.Location.ModelFactors.UpliftCriterionPiping.Value); +// break; +// case PipingModelType.Sellmeijer2Forces: calculator = new PipingCalculatorSellmeijer2Forces(modelParametersForPLLines, +// 1.0, null, null, job.Location.ModelFactors.UpliftCriterionPiping.Value); +// break; +// case PipingModelType.Sellmeijer4Forces: calculator = new PipingCalculatorSellmeijer4Forces(modelParametersForPLLines, +// 1.0, null, null, job.Location.ModelFactors.UpliftCriterionPiping.Value); +// break; +// case PipingModelType.Bligh: calculator = new PipingCalculatorBligh(modelParametersForPLLines, +// 1.0, null, null, job.Location.ModelFactors.UpliftCriterionPiping.Value); +// break; +// default: +// throw new RWScenariosCalculationException(String.Format("Piping model {0} not yet implemented for scenario calculation", job.PipingModelOption)); +// } +// return calculator; +// } /// /// Process a job for failuremechanism Stability /// /// private void ProcessJobStability(RWScenarioProfileResult job) { - StabilityCalculation calculator = new StabilityCalculation(); - - lock (runningJobs) - { - runningJobs[calculator] = job; - } - - calculator.MStabExePath = this.MStabExePath; - calculator.RegisterSendMessage(this.SendStabilityMessage); - - string soilDatabaseName = job.Location.SoildatabaseName; - DamFailureMechanismeCalculationSpecification damCalculation = - calculator.GetSpecification(this.evaluationJob.DikeName, soilDatabaseName, job.Location, new SoilGeometry(job.SoilGeometryProbability.SoilProfile, null), - (MStabModelType)job.MstabModelOption, job.LoadSituation, job.DikeDrySensitivity, job.HydraulicShortcutType, MStabParameters); - - calculator.SaveToFile(damCalculation.FailureMechanismeParamatersMStab); - - string inputFile = damCalculation.FailureMechanismeParamatersMStab.MStabParameters.ProjectFileName; - - job.BaseFileName = inputFile.Replace(DamProject.ProjectWorkingPath, @"").Replace(".sti", ""); - - calculator.Load(inputFile); - job.CalculationResult = calculator.Run(); - - if (job.CalculationResult == CalculationResult.Succeeded) - { - string results = ""; - - job.CalculationResult = calculator.GetResults(ref results); - XmlDeserializer deserializer = new XmlDeserializer(); - RWResult result = (RWResult)deserializer.XmlDeserializeFromString(results, typeof(RWResult)); - - job.SafetyFactor = result.SafetyFactor; - job.ProbabilityOfFailure = result.ProbabilityOfFailure; - job.RwResultType = result.RwResultType; - job.CalculationResult = result.CalculationResult; - } - else - { - job.RwResultType = (damCalculation.FailureMechanismeParamatersMStab.MStabParameters.IsProbabilistic ? RWResultType.ProbabilityOfFailure : RWResultType.SafetyFactor); - job.SafetyFactor = double.NaN; - job.ProbabilityOfFailure = double.NaN; - } - - lock (runningJobs) - { - runningJobs.Remove(calculator); - } +// StabilityCalculation calculator = new StabilityCalculation(); +// +// lock (runningJobs) +// { +// runningJobs[calculator] = job; +// } +// +// calculator.MStabExePath = this.MStabExePath; +// calculator.RegisterSendMessage(this.SendStabilityMessage); +// +// string soilDatabaseName = job.Location.SoildatabaseName; +// DamFailureMechanismeCalculationSpecification damCalculation = +// calculator.GetSpecification(this.evaluationJob.DikeName, soilDatabaseName, job.Location, new SoilGeometry(job.SoilGeometryProbability.SoilProfile, null), +// (MStabModelType)job.MstabModelOption, job.LoadSituation, job.DikeDrySensitivity, job.HydraulicShortcutType, MStabParameters); +// +// calculator.SaveToFile(damCalculation.FailureMechanismeParamatersMStab); +// +// string inputFile = damCalculation.FailureMechanismeParamatersMStab.MStabParameters.ProjectFileName; +// +// job.BaseFileName = inputFile.Replace(DamProject.ProjectWorkingPath, @"").Replace(".sti", ""); +// +// calculator.Load(inputFile); +// job.CalculationResult = calculator.Run(); +// +// if (job.CalculationResult == CalculationResult.Succeeded) +// { +// string results = ""; +// +// job.CalculationResult = calculator.GetResults(ref results); +// XmlDeserializer deserializer = new XmlDeserializer(); +// RWResult result = (RWResult)deserializer.XmlDeserializeFromString(results, typeof(RWResult)); +// +// job.SafetyFactor = result.SafetyFactor; +// job.ProbabilityOfFailure = result.ProbabilityOfFailure; +// job.RwResultType = result.RwResultType; +// job.CalculationResult = result.CalculationResult; +// } +// else +// { +// job.RwResultType = (damCalculation.FailureMechanismeParamatersMStab.MStabParameters.IsProbabilistic ? RWResultType.ProbabilityOfFailure : RWResultType.SafetyFactor); +// job.SafetyFactor = double.NaN; +// job.ProbabilityOfFailure = double.NaN; +// } +// +// lock (runningJobs) +// { +// runningJobs.Remove(calculator); +// } ##Bka } /// @@ -479,7 +488,7 @@ { RWScenarioProfileResult job = (RWScenarioProfileResult)runningJobs[(ICalculation)logMessage.Subject]; logMessage.Subject = job.Location; - logMessage.Detail = job.SoilGeometryProbability.SoilProfile.Name; + // logMessage.Detail = job.SoilGeometryProbability.SoilProfile.Name; } } Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/ParameterMissingException.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/ParameterMissingException.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/ParameterMissingException.cs (revision 330) @@ -0,0 +1,47 @@ +// 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; + +namespace Deltares.DamEngine.Calculators.General +{ + [Serializable] + public class ParameterMissingException : Exception + { + public ParameterMissingException(string messageFormat) + : base(messageFormat, null) + { + } + + public ParameterMissingException(string messageFormat, Exception inner) + : base(string.Format(messageFormat), inner) + { + } + + protected ParameterMissingException( + SerializationInfo info, + StreamingContext context) + : base(info, context) + { + } + } +} \ No newline at end of file Fisheye: Tag 330 refers to a dead (removed) revision in file `dam engine/branches/Initial Source/Deltares.DamEngine.Controllers/PLLinesCreator.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Uplift/UpliftLocationDeterminator.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Uplift/UpliftLocationDeterminator.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Uplift/UpliftLocationDeterminator.cs (revision 330) @@ -0,0 +1,322 @@ +// 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.Collections.Generic; +using System.Linq; +using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.General.PlLines; +using Deltares.DamEngine.Data.Geometry; +using Deltares.DamEngine.Data.Geotechnics; + +namespace Deltares.DamEngine.Calculators.Uplift +{ + /// + /// Exception for UpliftLocationDeterminator class + /// + public class UpliftLocationDeterminatorException : 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 UpliftLocationDeterminatorException() { } + public UpliftLocationDeterminatorException(string message) : base(message) { } + } + + /// + /// Data class containing information about uplift location and uplift factor + /// + public class UpliftLocationAndResult : GeometryPoint + { + public UpliftLocationAndResult() + { + UpliftFactor = 0; + LayerWhereUpliftOccuresId = ""; + } + + public UpliftLocationAndResult(double upliftFactor, string layerWhereUpliftOccuresId) + { + UpliftFactor = upliftFactor; + LayerWhereUpliftOccuresId = layerWhereUpliftOccuresId; + } + + public UpliftLocationAndResult(GeometryPoint point, double upliftFactor, string layerWhereUpliftOccuresId) + { + X = point.X; + Y = point.Y; + Z = point.Z; + UpliftFactor = upliftFactor; + LayerWhereUpliftOccuresId = layerWhereUpliftOccuresId; + } + + public double? UpliftFactor { get; set; } + public string LayerWhereUpliftOccuresId { get; set; } + } + + /// + /// Determie uplift location and uplift factor + /// + public class UpliftLocationDeterminator + { + public bool IsUseOvenDryUnitWeight { get; set; } + public PLLines PLLines { get; set; } + public SurfaceLine2 SurfaceLine { get; set; } + public SoilProfile1D SoilProfile { get; set; } + public SoilProfile2D SoilProfile2D { get; set; } + public string SoilGeometry2DName { get; set; } + public Soil DikeEmbankmentMaterial { get; set; } + // public SoilbaseDB SoilBaseDB { get; set; } + public SoilList SoilList { get; set; } + public double XSoilGeometry2DOrigin { get; set; } + + /// + /// Constructor + /// + public UpliftLocationDeterminator() + { + IsUseOvenDryUnitWeight = false; + } + + /// + /// Get location nearest dike with and upliftfactor lower than required + /// + /// location and upliftfactor + public UpliftLocationAndResult GetLocationAndResult(double upliftCriterion) + { + ThrowIfNoPLLinesDefined(); + ThrowIfNoSurfaceLinDefined(); + ThrowIfNoSoilProfileDefined(); + + return GetLocationInPolderNearestDikeWithUpliftFactorLowerThanRequired(upliftCriterion); + } + + /// + /// Get location nearest dike with and upliftfactor lower than required + /// + /// location and upliftfactor + public UpliftLocationAndResult GetLocationInPolderNearestDikeWithUpliftFactorLowerThanRequired(double upliftCriterion) + { + ThrowIfNoPLLinesDefined(); + ThrowIfNoSurfaceLinDefined(); + ThrowIfNoSoilProfileDefined(); + + GeometryPoint startSurfacePoint = SurfaceLine.GetDikeToeInward(); + + IEnumerable relevantSurfacePointsList = from GeometryPoint point in SurfaceLine.Geometry.Points + where point.X >= startSurfacePoint.X + orderby point.X ascending + select point; + + bool foundUpliftFactor = false; + UpliftLocationAndResult upliftLocationAndResult = null; + foreach (GeometryPoint surfacePoint in relevantSurfacePointsList) + { + upliftLocationAndResult = GetUpliftFactorAtPoint(surfacePoint); + if ((upliftLocationAndResult != null) && (upliftLocationAndResult.UpliftFactor < upliftCriterion)) + { + foundUpliftFactor = true; + upliftLocationAndResult.X = surfacePoint.X; + upliftLocationAndResult.Z = surfacePoint.Z; + break; + } + } + return (foundUpliftFactor == true) ? upliftLocationAndResult : null; + } + + /// + /// Create upliftcalculator at given point + /// + /// GeometryPoint for which to calculate upliftfactor + /// Top of layer where uplift occurs + /// location and upliftfactor + private UpliftCalculator CreateUpliftCalculator(GeometryPoint point, double topOfLayer, SoilProfile1D soilProfile) + { + PLLine phreaticLine = PLLines.Lines[PLLineType.PL1]; + return new UpliftCalculator + { + + PhreaticLevel = phreaticLine.ZFromX(point.X), + SoilProfile = soilProfile, + TopOfLayerToBeEvaluated = topOfLayer, + SurfaceLevel = point.Z, + UnitWeightSoilEmbankment = (this.DikeEmbankmentMaterial == null) ? (double?) null : this.DikeEmbankmentMaterial.AbovePhreaticLevel, + IsUseOvenDryUnitWeight = this.IsUseOvenDryUnitWeight + }; + } + + /// + /// Calculate upliftfactor for given point + /// + /// + /// location and upliftfactor + public UpliftLocationAndResult GetUpliftFactorAtPoint(GeometryPoint point) + { + SoilProfile1D soilProfileInCurrentPoint = GetSoilProfileBelowPoint(point.X); + double upliftFactorForInBetweenSandLayer = double.MaxValue; + if (soilProfileInCurrentPoint.InBetweenAquiferLayer != null) + { + // Check if inbetween sandlayer below surface + double topInBetweenSandLayer = soilProfileInCurrentPoint.InBetweenAquiferLayer.TopLevel; + if (topInBetweenSandLayer < point.Z) + { + // There is an aquitard above the aquifer, for which we can determine the uplift factor + UpliftCalculator upliftCalculatorForInBetweenSandLayer = CreateUpliftCalculator(point, topInBetweenSandLayer, soilProfileInCurrentPoint); + if ( (PLLines.Lines[PLLineType.PL4] != null) && (PLLines.Lines[PLLineType.PL4].Points.Count > 0 )) + upliftFactorForInBetweenSandLayer = upliftCalculatorForInBetweenSandLayer.CalculateUpliftFactor(PLLines.Lines[PLLineType.PL4].ZFromX(point.X)); + } + else + { + if (soilProfileInCurrentPoint.GetBottomLevel(soilProfileInCurrentPoint.InBetweenAquiferLayer) < point.Z) + { + // The surface cuts into the aquifer so the level to be evaluated is at surfacelevel + UpliftCalculator upliftCalculatorForInBetweenSandLayer = CreateUpliftCalculator(point, point.Z, soilProfileInCurrentPoint); + if ((PLLines.Lines[PLLineType.PL4] != null) && (PLLines.Lines[PLLineType.PL4].Points.Count > 0)) + upliftFactorForInBetweenSandLayer = upliftCalculatorForInBetweenSandLayer.CalculateUpliftFactor(PLLines.Lines[PLLineType.PL4].ZFromX(point.X)); + + } + } + } + + double upliftFactorForBottomSandLayer = double.MaxValue; + if (soilProfileInCurrentPoint.BottomAquiferLayer != null) + { + // Check if bottom sandlayer below surface + double topBottomSandLayer = soilProfileInCurrentPoint.BottomAquiferLayer.TopLevel; + if (topBottomSandLayer < point.Z) + { + UpliftCalculator upliftCalculatorForBottomSandLayer = CreateUpliftCalculator(point, soilProfileInCurrentPoint.BottomAquiferLayer.TopLevel, soilProfileInCurrentPoint); + if ((PLLines.Lines[PLLineType.PL3] != null) && (PLLines.Lines[PLLineType.PL3].Points.Count > 0)) + upliftFactorForBottomSandLayer = upliftCalculatorForBottomSandLayer.CalculateUpliftFactor(PLLines.Lines[PLLineType.PL3].ZFromX(point.X)); + } + else + { + if (soilProfileInCurrentPoint.GetBottomLevel(soilProfileInCurrentPoint.BottomAquiferLayer) < point.Z) + { + // The surface cuts into the aquifer so the level to be evaluated is at surfacelevel + UpliftCalculator upliftCalculatorForInBetweenSandLayer = CreateUpliftCalculator(point, point.Z, soilProfileInCurrentPoint); + if ((PLLines.Lines[PLLineType.PL3] != null) && (PLLines.Lines[PLLineType.PL3].Points.Count > 0)) + upliftFactorForBottomSandLayer = upliftCalculatorForInBetweenSandLayer.CalculateUpliftFactor(PLLines.Lines[PLLineType.PL3].ZFromX(point.X)); + + } + } + + } + + if((upliftFactorForBottomSandLayer == double.MaxValue) && (upliftFactorForInBetweenSandLayer == double.MaxValue)) + return null; + + if (upliftFactorForBottomSandLayer < upliftFactorForInBetweenSandLayer) + { + return new UpliftLocationAndResult(point, upliftFactorForBottomSandLayer, soilProfileInCurrentPoint.BottomAquiferLayer.Name); + } + else + { + return new UpliftLocationAndResult(point, upliftFactorForInBetweenSandLayer, soilProfileInCurrentPoint.InBetweenAquiferLayer.Name); + } + } + + /// + /// Determine location with lowest upliftfactor + /// + /// location and upliftfactor + public UpliftLocationAndResult GetLocationAtWithLowestUpliftFactor() + { + double? lowestUpliftFactor = null; + + ThrowIfNoPLLinesDefined(); + ThrowIfNoSurfaceLinDefined(); + ThrowIfNoSoilProfileDefined(); + + GeometryPoint startSurfacePoint = SurfaceLine.GetDikeToeInward(); + IEnumerable relevantSurfacePointsList = from GeometryPoint point in SurfaceLine.Geometry.Points + where point.X >= startSurfacePoint.X + orderby point.X ascending + select point; + UpliftLocationAndResult upliftLocationAndResult = null; + UpliftLocationAndResult lowestUpliftLocationAndResult = null; + foreach (GeometryPoint surfacePoint in relevantSurfacePointsList) + { + upliftLocationAndResult = GetUpliftFactorAtPoint(surfacePoint); + if (upliftLocationAndResult != null) + { + if (!lowestUpliftFactor.HasValue || upliftLocationAndResult.UpliftFactor < lowestUpliftFactor) + { + lowestUpliftFactor = upliftLocationAndResult.UpliftFactor; + lowestUpliftLocationAndResult = upliftLocationAndResult; + } + } + } + return lowestUpliftLocationAndResult; + } + + /// + /// + /// + /// + /// + private SoilProfile1D GetSoilProfileBelowPoint(double xCoordinate) + { + if (this.SoilProfile != null) + { + return this.SoilProfile; + } + if (SoilProfile2D != null) + { + return SoilProfile2D.GetSoilProfile1D(xCoordinate); + } + // Geometry2DTo1DConverter geometry2DTo1DConverter = new Geometry2DTo1DConverter(this.SoilGeometry2DName, this.SurfaceLine, this.DikeEmbankmentMaterial, this.SoilBaseDB, this.SoilList, -this.XSoilGeometry2DOrigin); ##BKA Replace with Conversion as used in DSM + // return geometry2DTo1DConverter.Convert(xCoordinate); + return null; + } + + /// + /// Check on precondition + /// + private void ThrowIfNoPLLinesDefined() + { + if (PLLines == null) + throw new UpliftLocationDeterminatorException("Required pllines not found"); + } + + /// + /// Check on precondition + /// + private void ThrowIfNoSurfaceLinDefined() + { + if (SurfaceLine == null) + throw new UpliftLocationDeterminatorException("Required surfaceLine line not found"); + } + + /// + /// Check on precondition + /// + private void ThrowIfNoSoilProfileDefined() + { + if (SoilProfile == null && (SoilGeometry2DName == null || SoilGeometry2DName == "") && SoilProfile2D == null) + throw new UpliftLocationDeterminatorException("Required soilProfile not found"); + } + + } +} Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Uplift/UpliftCalculator.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Uplift/UpliftCalculator.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Uplift/UpliftCalculator.cs (revision 330) @@ -0,0 +1,193 @@ +// 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"); + } + } + } +} \ No newline at end of file Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Design/SurfaceLineAdapter.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Design/SurfaceLineAdapter.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Design/SurfaceLineAdapter.cs (revision 330) @@ -0,0 +1,494 @@ +// 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.Collections.Generic; +using System.Linq; +using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.Geometry; +using Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.Data.Standard; +using Deltares.DamEngine.Data.Standard.Language; + +namespace Deltares.DamEngine.Calculators.General +{ + public struct DitchDefinition + { + public double OriginalX; + public double DistanceFromToe; + public double DistanceToBottomDikeSide; + public double DistanceToBottomPolderSide; + public double DistanceToEndDitch; + public double DepthBottomDikeSide; + public double DepthBottomPolderSide; + } + + public abstract class SurfaceLineAdapter + { + + private struct DitchCoordinates + { + public double XAtDike; + public double ZAtDike; + public double XBottomAtDike; + public double ZBottom; + public double XBottomAtPolder; + public double XAtPolder; + public double ZAtPolder; + } + + protected readonly Location Location; + protected readonly SurfaceLine2 surfaceLine; + protected double trafficLoadOffsetXfromRiverside; + protected double trafficLoadOffsetXfromPolderside; + protected double trafficLoadWidth; + protected bool hasTrafficLoad; + protected bool isTrafficLoadOnCrest = false; + const double offset = 100.0; + + /// + /// Constructor + /// + /// + /// + protected SurfaceLineAdapter(SurfaceLine2 surfaceLine, Location location) + { + ThrowWhenSurfaceLineIsNull(surfaceLine); + ThrowWhenSurfaceLineDoesNotSatisfyToSpecification(surfaceLine); + this.surfaceLine = new SurfaceLine2(); + surfaceLine.CloneProperties(this.surfaceLine);// ##Bka: replaced FullDeepClone(); by this (as todo says, has to be tested)// TODO: Do not do this! Give it the clone instead: GRASP Creator principle + this.Location = location; + RetainTrafficLoad(); + } + + /// + /// Store the parameters with which the traffic load can be restored. + /// The traffic load will be retained relative to the buitenkruinlijn. + /// If the traffic load is completly inside area between buitenkruinlijn and binnenkruinlijn the following will be done: + /// - The traffic load will be retained relative to the binnenkruinlijn. If the leftside of the traffic load passes the buitenkruinlijn, + /// the leftside of the traffic load will be placed on the buitenkruinlijn. It is possible that the rightside of the traffic load + /// passes the buitenkruinlijn. + /// See documentation in Issue [MWDAM-548] + /// + private void RetainTrafficLoad() + { + GeometryPoint pointTrafficLoadInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadInside); + GeometryPoint pointTrafficLoadOutside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadOutside); + GeometryPoint pointDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver); + GeometryPoint pointDikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); + + hasTrafficLoad = ((pointTrafficLoadInside != null) && (pointTrafficLoadOutside != null)); + if (hasTrafficLoad) + { + trafficLoadOffsetXfromRiverside = pointTrafficLoadOutside.X - pointDikeTopAtRiver.X; + trafficLoadOffsetXfromPolderside = pointDikeTopAtPolder.X - pointTrafficLoadInside.X; + trafficLoadWidth = pointTrafficLoadInside.X - pointTrafficLoadOutside.X; + isTrafficLoadOnCrest = (pointTrafficLoadOutside.X >= pointDikeTopAtRiver.X) && (pointTrafficLoadInside.X <= pointDikeTopAtPolder.X); + } + + } + + /// + /// Create traffic load based on the retained traffic load parameters + /// See documentation in Issue [MWDAM-548] + /// + protected void RestoreTrafficLoad() + { + if (hasTrafficLoad) + { + GeometryPoint pointDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver); + GeometryPoint pointDikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); + if (isTrafficLoadOnCrest) + { + // The traffic load will be restored relative to the binnenkruinlijn. If the leftside of the traffic load passes the buitenkruinlijn, + // the leftside of the traffic load will be placed on the buitenkruinlijn. It is possible that the rightside of the traffic load + // passes the buitenkruinlijn. + surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX + double xCoordinate = pointDikeTopAtPolder.X - trafficLoadOffsetXfromPolderside - trafficLoadWidth; + if (xCoordinate < pointDikeTopAtRiver.X) + { + xCoordinate = pointDikeTopAtRiver.X; + } + double zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate); + surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadOutside); + + surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX + xCoordinate += trafficLoadWidth; + zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate); + surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadInside); + } + else + { + // The traffic load will be restore relative to the buitenkruinlijn. + surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX + double xCoordinate = pointDikeTopAtRiver.X + trafficLoadOffsetXfromRiverside; + double zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate); + surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadOutside); + + surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX + xCoordinate = pointDikeTopAtRiver.X + trafficLoadOffsetXfromRiverside + trafficLoadWidth; + zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate); + surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadInside); + } + } + } + + /// + /// Replaces the inside slope by adding the new end point of the slope to the surfaceline. + /// + /// + /// + /// point equal to the ShoulderTopInside when the new slope ends on that point else null + protected GeometryPoint ReplaceBaseInsideForNewSlope(GeometryPoint startPoint, double slopeTangent) + { + GeometryPoint result = null; + var line = new Line + { + BeginPoint = new Point2D(startPoint.X, startPoint.Z), + EndPoint = + new Point2D(startPoint.X + offset, + startPoint.Z - offset * slopeTangent) + }; + // Find the intersectionpoint(s) of the new slope with the surface line + var intersectionpoints = surfaceLine.Geometry.IntersectionPointsXzWithLineXz(line); + Point2D newSlopeEndPoint = null; + if (intersectionpoints.Count > 0) + { + newSlopeEndPoint = intersectionpoints.First(); + // One of the intersection points can be the dike top which should not be replaced + if (newSlopeEndPoint.X == surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X && + newSlopeEndPoint.Z == surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z) + { + newSlopeEndPoint = null; + if (intersectionpoints.Count > 1) + { + newSlopeEndPoint = intersectionpoints[1]; + } + } + } + if (newSlopeEndPoint == null) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SlopeErrorNoIntersection")); + } + var dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + if (newSlopeEndPoint.X > dikeToeAtPolder.X) + { + // The new point is beyond the old dike toe so adapt that point. + surfaceLine.EnsurePointOfType(newSlopeEndPoint.X, newSlopeEndPoint.Z, CharacteristicPointType.DikeToeAtPolder); + // Remove all points between top and dike toe, + surfaceLine.RemoveSegmentBetween( + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X, + newSlopeEndPoint.X); + } + else + { + var shoulderTopInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + var shoulderBaseInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + if (shoulderBaseInside != null && shoulderTopInside != null) + { + if (newSlopeEndPoint.X > shoulderTopInside.X) + { + // The new point is in the slope part of the shoulder (between ShoulderTopInside and Dike toe). So add a normal point + // at the new location and remove all points between the top and the new point. + //surfaceLine.RemovePoint(CharacteristicPointType.); + surfaceLine.EnsurePoint(newSlopeEndPoint.X, newSlopeEndPoint.Z); + surfaceLine.RemoveSegmentBetween( + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X, + newSlopeEndPoint.X); + } + else + { + if (newSlopeEndPoint.X < shoulderTopInside.X) + { + // The new point is in the horizontal part of the shoulder. Remove all points between the current + // shoulderbase inside and its new location, then move the base + surfaceLine.RemoveSegmentBetween(shoulderBaseInside.X, newSlopeEndPoint.X); + surfaceLine.EnsurePointOfType(newSlopeEndPoint.X, newSlopeEndPoint.Z, + CharacteristicPointType.ShoulderBaseInside); + + } + else + { + // The new point is equal to ShoulderTopInside. So remove that, add a normal point at its location + // and remove all points between the top and the new point. + var toBeRemoved = surfaceLine.CharacteristicPoints.FirstOrDefault( + cp => cp.CharacteristicPointType == CharacteristicPointType.ShoulderTopInside); + if (toBeRemoved != null) + { + surfaceLine.CharacteristicPoints.Remove(toBeRemoved); + } + surfaceLine.EnsurePoint(newSlopeEndPoint.X, newSlopeEndPoint.Z); + surfaceLine.RemoveSegmentBetween( + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X, + newSlopeEndPoint.X); + result = new GeometryPoint(newSlopeEndPoint.X, newSlopeEndPoint.Z); + } + } + } + else + { + // if the newtoe equals the diketoe, then just skip, nothing has to be changed. Otherwise there is a mistake! + if (!newSlopeEndPoint.LocationEquals(new Point2D(dikeToeAtPolder.X, dikeToeAtPolder.Z))) + { + // There is no shoulder so the slope must be too steep. + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, + "SlopeErrorNoIntersection")); + } + } + } + surfaceLine.SortPoints(); + return result; + } + + /// + /// Throws an exception when the surface line does not comply to the specification + /// + /// + /// The specification is that there: + /// - There are should be at least 4 points in the surface line + /// - must be a dike + /// - that the point coords are non zero + /// - There is a surface line when a shoulder exists + /// + /// The candidate to test + private static void ThrowWhenSurfaceLineDoesNotSatisfyToSpecification(SurfaceLine2 surfaceLine) + { + ThrowWhenSurfaceLineHasNoOrLessThenFourPoints(surfaceLine.Geometry.Points); + ThrowWhenSurfaceHasNoDike(surfaceLine); + ThrowWhenSurfaceLineHasAShoulderInsideAndNoSurfaceLevel(surfaceLine, + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside)); + + var p1 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver); + var p2 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); + + var zeroPoint = new GeometryPoint(); + + if (zeroPoint.LocationEquals(p1) || zeroPoint.LocationEquals(p2)) + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(typeof(SurfaceLineAdapter), + "SurfaceLineAdapterDikeHeightError")); + + if (surfaceLine.HasShoulderInside()) + { + p1 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + p2 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + if (zeroPoint.LocationEquals(p1) || zeroPoint.LocationEquals(p2)) + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(typeof(SurfaceLineAdapter), + "SurfaceLineAdapterShoulderHeightError")); + } + } + + private static void ThrowWhenSurfaceLineHasAShoulderInsideAndNoSurfaceLevel(SurfaceLine2 surfaceLine, GeometryPoint surfaceLevelPoint) + { + if (surfaceLine.HasShoulderInside() && surfaceLevelPoint == null) + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(typeof(SurfaceLineAdapter), + "SurfaceLineAdapterSurfaceLevelError")); + } + + private static void ThrowWhenSurfaceHasNoDike(SurfaceLine2 surfaceLine) + { + if (!surfaceLine.HasDike()) + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(typeof(SurfaceLineAdapter), + "SurfaceLineAdapterInvalidDikeError")); + } + + private static void ThrowWhenSurfaceLineIsNull(SurfaceLine2 surfaceLine) + { + if (surfaceLine == null) + throw new ArgumentNullException("SurfaceLine", LocalizationManager.GetTranslatedText(typeof(SurfaceLineAdapter), + "SurfaceLineAdapterNoDikeError")); + } + + private static void ThrowWhenSurfaceLineHasNoOrLessThenFourPoints(ICollection points) + { + if (points == null || points.Count < 4) + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(typeof(SurfaceLineAdapter), + "SurfaceLineAdapterNoDikePointsError")); + } + + protected DitchDefinition? GetDitchDefinition() + { + var ditchDefinition = new DitchDefinition(); + if (surfaceLine.HasDitch() && surfaceLine.IsDitchCorrect()) + { + var ditchDikeSide = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + ditchDefinition.DistanceFromToe = ditchDikeSide.X - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; + if (ditchDefinition.DistanceFromToe >= 0) + { + ditchDefinition.OriginalX = ditchDikeSide.X; + ditchDefinition.DistanceToBottomDikeSide = + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide).X - + ditchDikeSide.X; + ditchDefinition.DistanceToBottomPolderSide = + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide).X - + ditchDikeSide.X; + ditchDefinition.DistanceToEndDitch = + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X - + ditchDikeSide.X; + ditchDefinition.DepthBottomDikeSide = ditchDikeSide.Z - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide).Z; + ditchDefinition.DepthBottomPolderSide = ditchDikeSide.Z - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide).Z; + return ditchDefinition; + } + } + else + { + if (surfaceLine.HasDitch()) + { + // Incorrect ditch is an error here, this should have been checked already + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(typeof(SurfaceLineAdapter), + "SurfaceLineAdapterDikeDitchError")); + } + } + return null; + } + + /// + /// Removes the existing ditch. + /// + /// The ditch definition. + protected void RemoveExistingDitch(DitchDefinition? ditchDefinition) + { + if (ditchDefinition != null) + { + // It is possible that DikeToeAtPolder coinsides with DitchDikeSide or SurfaceLevelInside with DitchPolderSide + // If that is the case, those characteristic points should be restored + // So first save those characteristic points + GeometryPoint dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + GeometryPoint surfaceLevelInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside); + // The characteristic points DitchDikeSide and DitchPolderSide should be removed, but the points itself should be restored, + // else the surfaceline will get a new form. So save those points + GeometryPoint ditchDikeSide = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + GeometryPoint ditchPolderSide = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + surfaceLine.RemoveSegmentIncluding( + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide).X, + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X); + // Now restore characteristic points DikeToeAtPolder and SurfaceLevelInside if necessary + surfaceLine.EnsurePointOfType(dikeToeAtPolder.X, dikeToeAtPolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(surfaceLevelInside.X, surfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + // Now restore points ditchDikeSide and ditchPolderSide + surfaceLine.EnsurePoint(ditchDikeSide.X, ditchDikeSide.Z); + surfaceLine.EnsurePoint(ditchPolderSide.X, ditchPolderSide.Z); + surfaceLine.SortPoints(); + } + } + + private DitchCoordinates GetCoordinatesForOldShape(double xDitchDike, DitchDefinition ditchDefinition) + { + var res = new DitchCoordinates(); + res.XAtDike = xDitchDike; + res.ZAtDike = surfaceLine.Geometry.GetZatX(res.XAtDike); + res.XBottomAtDike = xDitchDike + ditchDefinition.DistanceToBottomDikeSide; + res.ZBottom = res.ZAtDike - ditchDefinition.DepthBottomDikeSide; + res.XBottomAtPolder = xDitchDike + ditchDefinition.DistanceToBottomPolderSide; + res.XAtPolder = xDitchDike + ditchDefinition.DistanceToEndDitch; + res.ZAtPolder = surfaceLine.Geometry.GetZatX(res.XAtPolder); + return res; + } + + private DitchCoordinates GetCoordinatesForNewShape(double xDitchDike) + { + var res = new DitchCoordinates(); + res.XAtDike = xDitchDike; + res.ZAtDike = surfaceLine.Geometry.GetZatX(res.XAtDike); + // Depth of the ditch is defined towards PolderLevel + res.ZBottom = Location.PolderLevel - Location.NewDepthDitch; + res.XBottomAtDike = xDitchDike + (res.ZAtDike - res.ZBottom)*Location.NewSlopeAngleDitch; + res.XBottomAtPolder = res.XBottomAtDike + Location.NewWidthDitchBottom; + var line = new Line + { + BeginPoint = new Point2D(res.XBottomAtPolder, res.ZBottom), + EndPoint = new Point2D(res.XBottomAtPolder + offset, + res.ZBottom + offset * Location.NewSlopeAngleDitch) + }; + // Find the intersectionpoint(s) of the new ditch slope with the surface line + var intersectionpoints = surfaceLine.Geometry.IntersectionPointsXzWithLineXz(line); + if (intersectionpoints.Count > 0) + { + res.XAtPolder = intersectionpoints[0].X; + res.ZAtPolder = intersectionpoints[0].Z; + } + else + { + //new slope of ditch does not intersect with surface line (most probably because the bottom is too high) + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(typeof(SurfaceLineAdapter), + "SurfaceLineAdapterDitchSlopeError")); + } + return res; + } + + protected void RestoreDitch(DitchDefinition? ditchDefinition) + { + if (ditchDefinition == null) return; + var dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + double distanceToNewToe = ditchDefinition.Value.OriginalX - dikeToeAtPolder.X; + double xDitchDikeSide; + DitchCoordinates coors; + surfaceLine.SortPoints(); + // First determine all coordinates + if (distanceToNewToe < Location.NewMinDistanceDikeToeStartDitch && distanceToNewToe != ditchDefinition.Value.DistanceFromToe) + { + // Ditch needs to be moved as it is less then the minimum required distance from the new toe + xDitchDikeSide = dikeToeAtPolder.X + + Location.NewMinDistanceDikeToeStartDitch; + if (Location.UseNewDitchDefinition) + { + // Use the new definition instead of the old shape + coors = GetCoordinatesForNewShape(xDitchDikeSide); + + } + else + { + // replace the ditch with the same shape. + coors = GetCoordinatesForOldShape(xDitchDikeSide, ditchDefinition.Value); + } + } + else + { + // replace the ditch with the same shape and same location. + xDitchDikeSide = dikeToeAtPolder.X + + distanceToNewToe; + coors = GetCoordinatesForOldShape(xDitchDikeSide, ditchDefinition.Value); + } + // check if the new bottom is beneath the surface line. If not, the ditch must not be replaced at all + if (coors.ZBottom >= surfaceLine.Geometry.GetZatX(coors.XBottomAtDike) || + coors.ZBottom >= surfaceLine.Geometry.GetZatX(coors.XBottomAtPolder)) + { + return; + } + double surfaceLevelInsideX = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X; + if (coors.XAtPolder > surfaceLevelInsideX) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineHeightAdapterDitchOutsideSurfaceLine")); + } + // Add the outside points of the new ditch + surfaceLine.EnsurePointOfType(coors.XAtDike, coors.ZAtDike, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(coors.XAtPolder, coors.ZAtPolder, CharacteristicPointType.DitchPolderSide); + // Delete all existing points in the new ditch + surfaceLine.RemoveSegmentBetween(coors.XAtDike, coors.XAtPolder); + // Add the bottom of the ditch + surfaceLine.EnsurePointOfType(coors.XBottomAtDike, coors.ZBottom, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(coors.XBottomAtPolder, coors.ZBottom, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.SortPoints(); + } + } +} \ No newline at end of file Fisheye: Tag 330 refers to a dead (removed) revision in file `dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/UpliftRWEvaluator.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/SchematizationFactor/SchematizationFactorCalculation.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/SchematizationFactor/SchematizationFactorCalculation.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/SchematizationFactor/SchematizationFactorCalculation.cs (revision 330) @@ -0,0 +1,405 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.General.Results; +using Deltares.DamEngine.Data.General.SchematizationFactor; +using Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.Data.RWScenarios; +using Deltares.DamEngine.Data.Standard.Calculation; + +namespace Deltares.DamEngine.Calculators.SchematizationFactor +{ + public class SchematizationFactorIntermediate + { + private SoilProfile1D soilProfile; + private double safetyFactor; + private double probPercentage; + private double summedProbPercentage; + + public SoilProfile1D SoilProfile + { + get { return soilProfile; } + set { soilProfile = value; } + } + + public double SafetyFactor + { + get { return safetyFactor; } + set { safetyFactor = value; } + } + + public double ProbPercentage + { + get { return probPercentage; } + set { probPercentage = value; } + } + + public double SummedProbPercentage + { + get { return summedProbPercentage; } + set { summedProbPercentage = value; } + } + } + + public class SchematizationFactorIntermediateList + { + private List schematizationFactorIntermediates = new List(); + + public List SchematizationFactorIntermediates + { + get { return schematizationFactorIntermediates; } + set { schematizationFactorIntermediates = value; } + } + + public void SortBySafetyFactor() + { + // First sort on prob + var sorted1 = schematizationFactorIntermediates.OrderByDescending(item => item.ProbPercentage); + List res1 = new List(); + foreach (var schematizationFactorIntermediate in sorted1) + { + res1.Add(schematizationFactorIntermediate); + } + schematizationFactorIntermediates.Clear(); + schematizationFactorIntermediates = res1; + + // then sort on sf. + var sorted = schematizationFactorIntermediates.OrderByDescending(item => item.SafetyFactor); + List res = new List(); + + foreach (var schematizationFactorIntermediate in sorted) + { + res.Add(schematizationFactorIntermediate); + } + schematizationFactorIntermediates.Clear(); + schematizationFactorIntermediates = res; + } + + public void SumSoilProfileProbabilities() + { + for (int i = 0; i < schematizationFactorIntermediates.Count; i++) + { + if (i == 0) + { + schematizationFactorIntermediates[i].SummedProbPercentage = + schematizationFactorIntermediates[i].ProbPercentage; + } + else + { + schematizationFactorIntermediates[i].SummedProbPercentage = + schematizationFactorIntermediates[i - 1].SummedProbPercentage + + schematizationFactorIntermediates[i].ProbPercentage; + } + } + } + + public int GetBasicSchematization(double requiredProbability) + { + var result = schematizationFactorIntermediates.Count - 1; + for (int i = 0; i < schematizationFactorIntermediates.Count; i++) + { + if (schematizationFactorIntermediates[i].SummedProbPercentage >= requiredProbability) + { + result = i; + break; + } + } + return result; + } + } + + public class SchematizationFactorCalculation + { + private RWScenariosResult scenariosResult; // input: scenariosResult are the results of all scenarios for one location. + private double detrimentFactor = 0; + private SchematizationFactorData schematizationFactorData; + private Location location; + + public RWScenariosResult ScenariosResult + { + get { return scenariosResult; } + set { scenariosResult = value; } + } + + public double DetrimentFactor + { + get { return detrimentFactor; } + set { detrimentFactor = value; } + } + + public SchematizationFactorData SchematizationFactorData + { + get { return schematizationFactorData; } + set { schematizationFactorData = value; } + } + + public Location Location + { + get { return location; } + set { location = value; } + } + + public RWSchematizationFactorsResult CalculateSchematizationFactorResults() + { + CheckData(); + + var results = new RWSchematizationFactorsResult(); + var macroStabilityInnerSideWetResult = + CalculateSchematizationFactorResultForType(SchematizationType.MacroStabiltyInnerSideWet); + results.SchematizationFactorResults.Add(macroStabilityInnerSideWetResult); + + var macroStabiltyInnerSideDryResult = + CalculateSchematizationFactorResultForType(SchematizationType.MacroStabiltyInnerSideDry); + results.SchematizationFactorResults.Add(macroStabiltyInnerSideDryResult); + + return results; + } + + public RWSchematizationFactorResult CalculateSchematizationFactorResultForType(SchematizationType schematizationType) + { + CheckData(); + + var result = GetSchematizationFactorResult(schematizationType); + + return result; + } + + private void CheckData() + { + if (scenariosResult == null) + { + throw new ApplicationException("Scenario results must be available to calculate the Schematization Factor."); + } + + if (detrimentFactor <= 0.0001) + { + throw new ApplicationException("Detriment factor must be specified to calculate the Schematization Factor."); + } + + if (schematizationFactorData == null) + { + throw new ApplicationException("Schematization Factor Data must be available to calculate the Schematization Factor."); + } + + if (this.Location == null) + { + throw new ApplicationException("Location name must be available to calculate the Schematization Factor."); + } + } + + private RWSchematizationFactorResult GetSchematizationFactorResult(SchematizationType schematizationType) + { + var schematizationFactorResult = new RWSchematizationFactorResult(); + schematizationFactorResult.SchematizationType = schematizationType; + schematizationFactorResult.SchematizationFactor = schematizationFactorData.SchematizationFactorMin; + schematizationFactorResult.Location = this.Location; + schematizationFactorResult.DetrimentFactor = DetrimentFactor; + + var decisiveScenarioResults = GetDecisiveResultsPerSchematizationType(schematizationType); + if (decisiveScenarioResults != null) + { + var mswIntermediates = SortResultsSchematizationType(decisiveScenarioResults); + var basicSchematization = + mswIntermediates.GetBasicSchematization(schematizationFactorData.RequiredProbability); + var schematizationFactor = schematizationFactorData.SchematizationFactorMin; + var allowedProbability = DetermineAllowedProbabilty(); + if ((basicSchematization >= 0) && (CheckOnB6(mswIntermediates, allowedProbability))) + { +//#Bka hier de SummedProbPercentage initialiseren op 1e laag basisprofiel zodat het % niet op nul blijft staan als je direct aan B7 voldoet!!!! Nagaan bij Erik of dat klopt of dat + // hij toch liever 0 of 100% ziet. + schematizationFactorResult.SummedProfileProbability = + mswIntermediates.SchematizationFactorIntermediates[basicSchematization].SummedProbPercentage; + schematizationFactorResult.OriginalDecisiveSoilProfileName = mswIntermediates.SchematizationFactorIntermediates[basicSchematization].SoilProfile.Name; + while (!CheckOnB7(mswIntermediates, basicSchematization, allowedProbability, schematizationFactor)) + { + //increase Pallowed + schematizationFactor = schematizationFactor + schematizationFactorData.SchematizationFactorDelta; + if (schematizationFactor > schematizationFactorData.SchematizationFactorMax) + { + // reset the factor, go to the next schematization when possible + schematizationFactor = schematizationFactorData.SchematizationFactorMin; + if (basicSchematization < mswIntermediates.SchematizationFactorIntermediates.Count - 1) + { + basicSchematization++; + } + else + { + schematizationFactorResult.CalculationResult = CalculationResult.RunFailed; + break; + } + } + } + schematizationFactorResult.SchematizationFactor = schematizationFactor; + schematizationFactorResult.SummedProfileProbability = + mswIntermediates.SchematizationFactorIntermediates[basicSchematization].SummedProbPercentage; + schematizationFactorResult.SoilProfileName = + mswIntermediates.SchematizationFactorIntermediates[basicSchematization].SoilProfile.Name; + schematizationFactorResult.DecisiveScenarioName = decisiveScenarioResults.ScenarioType; + schematizationFactorResult.SafetyFactor = + mswIntermediates.SchematizationFactorIntermediates[basicSchematization].SafetyFactor; + } + else + { + schematizationFactorResult.CalculationResult = CalculationResult.RunFailed; + } + } + else + { + schematizationFactorResult.CalculationResult = CalculationResult.RunFailed; + } + + if (schematizationFactorResult.CalculationResult != CalculationResult.Succeeded) + { + schematizationFactorResult.SchematizationFactor = 0; + } + return schematizationFactorResult; + } + + private double DetermineProbabilty(double factor) + { +// var beta = 4 + ((factor - 1)/0.13); +// var prob = Probabilistic.Probabilistic.NormalDistribution(beta * -1); +// return prob;##Bka + return double.MaxValue; + } + + internal double DetermineAllowedProbabilty() + { + return DetermineProbabilty(detrimentFactor); + } + + private double DetermineProbabiltyForSchematization(double safetyFactor) + { + return DetermineProbabilty(safetyFactor); + } + + private SchematizationFactorIntermediateList SortResultsSchematizationType(RWScenarioResult result) + { + var intermediateResults = new SchematizationFactorIntermediateList(); + foreach (var rwScenarioProfileResult in result.RWScenarioProfileResults) + { + var inter = new SchematizationFactorIntermediate(); + inter.SafetyFactor = rwScenarioProfileResult.SafetyFactor; + inter.SoilProfile = rwScenarioProfileResult.SoilGeometryProbability.SoilProfile; + inter.ProbPercentage = rwScenarioProfileResult.SoilGeometryProbability.Probability; + intermediateResults.SchematizationFactorIntermediates.Add(inter); + } + intermediateResults.SortBySafetyFactor(); + intermediateResults.SumSoilProfileProbabilities(); + return intermediateResults; + } + + private RWScenarioResult GetDecisiveResultsPerSchematizationType(SchematizationType schematizationType) + { + RWScenarioResult result = null; + double minSafetyFactor = Double.MaxValue; + switch (schematizationType) + { + case SchematizationType.MacroStabiltyInnerSideWet: + { + // scenarios 3, 4, 7 and 8 are relevant. + foreach (RWScenarioResult scenarioResult in scenariosResult.RWScenarioResults) + { + //#bka: nagaan bij Erik/Tom of dit de bedoeling is! + // nog groter mogelijk probleem : ik krijg niet alle resultaten door. Van de 37 profiles krijg ik er hier maar + // 27 door omdat de rest gefaald is en daarmee geen deel zijn van de scenarioResults! + if (scenarioResult.CalculationResult == CalculationResult.Succeeded) + { + if ((scenarioResult.ScenarioType == ScenarioType.Scenario03) || (scenarioResult.ScenarioType == ScenarioType.Scenario04) || + (scenarioResult.ScenarioType == ScenarioType.Scenario07) || (scenarioResult.ScenarioType == ScenarioType.Scenario08)) + { + if (scenarioResult.SafetyFactor < minSafetyFactor) + { + minSafetyFactor = scenarioResult.SafetyFactor; + result = scenarioResult; + } + } + } + } + break; + } + case SchematizationType.MacroStabiltyInnerSideDry: + { + // scenarios 1, 2, 5 and 6 are relevant. + foreach (RWScenarioResult scenarioResult in scenariosResult.RWScenarioResults) + { + //#bka: nagaan bij Erik/Tom of dit de bedoeling is! Non Succceeded heeft sf = -1 dus komt goed bij bepaling B06. + if (scenarioResult.CalculationResult == CalculationResult.Succeeded) + { + if ((scenarioResult.ScenarioType == ScenarioType.Scenario01) || (scenarioResult.ScenarioType == ScenarioType.Scenario02) || + (scenarioResult.ScenarioType == ScenarioType.Scenario05) || (scenarioResult.ScenarioType == ScenarioType.Scenario06)) + { + if (scenarioResult.SafetyFactor < minSafetyFactor) + { + minSafetyFactor = scenarioResult.SafetyFactor; + result = scenarioResult; + } + } + } + } + break; + } + default: + { + throw new ApplicationException("Schematization Factor not yet implemented for other things than macro stability."); + } + + } + return result; + } + + /// + /// Checks condition B.6: sum of all ( P(D|Si) * P(Si) ) smaller than or equal to Pallowed + /// P(D|Si) is the probability of failure for the schematization i + /// P(Si) is the probability of occurence for the schematization i + /// + /// + /// + /// + private bool CheckOnB6(SchematizationFactorIntermediateList intermediates, double allowedProbability) + { + double summedProbability = 0; + foreach (var intermediate in intermediates.SchematizationFactorIntermediates) + { + summedProbability = summedProbability + (DetermineProbabiltyForSchematization(intermediate.SafetyFactor) * + (intermediate.ProbPercentage / 100)); + } + var result = (summedProbability <= allowedProbability); + return result; + } + + /// + /// Checks condition B.7: (1 - sum of P(Si)) * P(D|Sk) + sum of ( P(D|Si) * P(Si) ) smaller than or equal to Pallowed + /// Note that the summing starts at i = k+1 with k being the number of the basic schematization + /// P(D|Sk) is the probability of failure for the schematization k + /// P(D|Si) is the probability of failure for the schematization i + /// P(Si) is the probability of occurence for the schematization i + /// + /// + /// + /// + /// + /// + private bool CheckOnB7(SchematizationFactorIntermediateList intermediates, int basicScenario, double allowedProbability, double schematizationFactor) + { + var result = false; + if (basicScenario >= 0) + { + var summedProbability = (DetermineProbabiltyForSchematization(intermediates.SchematizationFactorIntermediates[basicScenario].SafetyFactor * + schematizationFactor) * (intermediates.SchematizationFactorIntermediates[basicScenario].SummedProbPercentage / 100.0)); ; + + for (int i = basicScenario + 1; i < intermediates.SchematizationFactorIntermediates.Count; i++) + { + var prob = DetermineProbabiltyForSchematization(intermediates.SchematizationFactorIntermediates[i].SafetyFactor*schematizationFactor)* + (intermediates.SchematizationFactorIntermediates[i].ProbPercentage/100.0); + summedProbability = summedProbability + prob; + } + result = (summedProbability <= allowedProbability); + } + return result; + + } + + } +} Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs =================================================================== diff -u -r276 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (.../GeometryPointString.cs) (revision 276) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (.../GeometryPointString.cs) (revision 330) @@ -492,7 +492,7 @@ /// /// /// - private IList IntersectionPointsXzWithLineXz(Line line) + public IList IntersectionPointsXzWithLineXz(Line line) { return IntersectionPointsWithLineCore(line, false); } Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamCalculation.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamCalculation.cs (.../DamCalculation.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamCalculation.cs (.../DamCalculation.cs) (revision 330) @@ -218,72 +218,72 @@ /// /// /// - private void CalculateFailureMechanismStabilityInsideMStab( - DamFailureMechanismeCalculationSpecification failureMechanismeCalculationSpecification, - string failureMechanismWorkingDirectory) - { - if (string.IsNullOrWhiteSpace(failureMechanismWorkingDirectory)) - throw new ArgumentException("Invalid working directory. The supplied string is empty or null.", "failureMechanismWorkingDirectory"); +// private void CalculateFailureMechanismStabilityInsideMStab( +// DamFailureMechanismeCalculationSpecification failureMechanismeCalculationSpecification, +// string failureMechanismWorkingDirectory) +// { +// if (string.IsNullOrWhiteSpace(failureMechanismWorkingDirectory)) +// throw new ArgumentException("Invalid working directory. The supplied string is empty or null.", "failureMechanismWorkingDirectory"); +// +// string stabilityWorkingPath = Path.GetFullPath(failureMechanismWorkingDirectory); +// +// var timeSerieStabilityCalculator = new TimeSerieStabilityCalculator +// { +// StabilityWorkingPath = stabilityWorkingPath, +// IsMStabCalculationOff = false, +// MStabExePath = this.mstabExePath, +// SendMessageDelegate = sendMessageDelegate +// }; +// +// if (!Directory.Exists(timeSerieStabilityCalculator.StabilityWorkingPath)) +// { +// Directory.CreateDirectory(timeSerieStabilityCalculator.StabilityWorkingPath); +// } +// int locationCounter = 0; +// var safetyFactorsTimeSerieCollection = new TimeSerieCollection(); +// foreach (DamJob damJob in (damProjectData.WaterBoardJob as WaterBoardJob).Jobs) +// { +// DikeJob dikeJob = damJob as DikeJob; +// foreach (LocationJob locationJob in dikeJob.Jobs) +// { +// if (locationJob.Run.Value && locationJob.WaterLevelTimeSerie != null) +// { +// TimeSerie safefactorsTimeSerie = timeSerieStabilityCalculator.CreateStabilityInsideSafetyFactorTimeSerie( +// locationJob.WaterLevelTimeSerie, +// dikeJob.Dike, +// locationJob.Location, +// locationCounter, +// ProjectDataDirectory, +// failureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters, +// null); +// locationJob.LocationResult.StabilityTimeSerie = safefactorsTimeSerie; +// safefactorsTimeSerie.LocationId = locationJob.Location.Name; +// safetyFactorsTimeSerieCollection.Series.Add(safefactorsTimeSerie); +// locationCounter++; +// } +// } +// timeSerieStabilityCalculator.IsCalculateAllStabilityProjectsAtOnce = true; +// timeSerieStabilityCalculator.CalculateSafetyFactorFromTimeSeries(TimeSerieParameters.StabilityInsideFactor.ToString(), +// dikeJob.Dike, safetyFactorsTimeSerieCollection); +// } +// ThrowHelper.ThrowWhenConditionIsTrue("No locations specified.",() => locationCounter == 0); +// } - string stabilityWorkingPath = Path.GetFullPath(failureMechanismWorkingDirectory); - - var timeSerieStabilityCalculator = new TimeSerieStabilityCalculator - { - StabilityWorkingPath = stabilityWorkingPath, - IsMStabCalculationOff = false, - MStabExePath = this.mstabExePath, - SendMessageDelegate = sendMessageDelegate - }; - - if (!Directory.Exists(timeSerieStabilityCalculator.StabilityWorkingPath)) - { - Directory.CreateDirectory(timeSerieStabilityCalculator.StabilityWorkingPath); - } - int locationCounter = 0; - var safetyFactorsTimeSerieCollection = new TimeSerieCollection(); - foreach (DamJob damJob in (damProjectData.WaterBoardJob as WaterBoardJob).Jobs) - { - DikeJob dikeJob = damJob as DikeJob; - foreach (LocationJob locationJob in dikeJob.Jobs) - { - if (locationJob.Run.Value && locationJob.WaterLevelTimeSerie != null) - { - TimeSerie safefactorsTimeSerie = timeSerieStabilityCalculator.CreateStabilityInsideSafetyFactorTimeSerie( - locationJob.WaterLevelTimeSerie, - dikeJob.Dike, - locationJob.Location, - locationCounter, - ProjectDataDirectory, - failureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters, - null); - locationJob.LocationResult.StabilityTimeSerie = safefactorsTimeSerie; - safefactorsTimeSerie.LocationId = locationJob.Location.Name; - safetyFactorsTimeSerieCollection.Series.Add(safefactorsTimeSerie); - locationCounter++; - } - } - timeSerieStabilityCalculator.IsCalculateAllStabilityProjectsAtOnce = true; - timeSerieStabilityCalculator.CalculateSafetyFactorFromTimeSeries(TimeSerieParameters.StabilityInsideFactor.ToString(), - dikeJob.Dike, safetyFactorsTimeSerieCollection); - } - ThrowHelper.ThrowWhenConditionIsTrue("No locations specified.",() => locationCounter == 0); - } - public void CalculateDamProject(DamProjectData damProject, string defaultProjectWorkingPath) { - damProjectData = damProject; - - // Set default working directory - if (ProjectWorkingDirectory.Equals("")) - { - ProjectWorkingDirectory = defaultProjectWorkingPath; - } - - this.failureMechanismIndex = -1; - ThrowHelper.ThrowWhenConditionIsTrue("No actual calculation specified.", - () => damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications.Count == 0); - - Parallel.Run(damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications, this.RunFailureMechanism, this.progressDelegate, this.MaxCalculationCores); +// damProjectData = damProject; +// +// // Set default working directory +// if (ProjectWorkingDirectory.Equals("")) +// { +// ProjectWorkingDirectory = defaultProjectWorkingPath; +// } +// +// this.failureMechanismIndex = -1; +// ThrowHelper.ThrowWhenConditionIsTrue("No actual calculation specified.", +// () => damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications.Count == 0); +// +// Parallel.Run(damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications, this.RunFailureMechanism, this.progressDelegate, this.MaxCalculationCores); } private int GetFailureMechanismIndex() @@ -295,16 +295,16 @@ } } - private void RunFailureMechanism(object task) - { - DamFailureMechanismeCalculationSpecification failureMechanismCalculationSpecification = (DamFailureMechanismeCalculationSpecification)task; - string failureMechanismWorkingDirectory = String.Format(@"{0}\FM{1}\", ProjectWorkingDirectory, GetFailureMechanismIndex()); - DeleteDirectoryWithFiles(failureMechanismWorkingDirectory); - if (failureMechanismCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) - { - CalculateFailureMechanismStabilityInsideMStab(failureMechanismCalculationSpecification, failureMechanismWorkingDirectory); - } - } +// private void RunFailureMechanism(object task) +// { +// DamFailureMechanismeCalculationSpecification failureMechanismCalculationSpecification = (DamFailureMechanismeCalculationSpecification)task; +// string failureMechanismWorkingDirectory = String.Format(@"{0}\FM{1}\", ProjectWorkingDirectory, GetFailureMechanismIndex()); +// DeleteDirectoryWithFiles(failureMechanismWorkingDirectory); +// if (failureMechanismCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) +// { +// CalculateFailureMechanismStabilityInsideMStab(failureMechanismCalculationSpecification, failureMechanismWorkingDirectory); +// } +// } /// /// Delete all files in directory and all files in it Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Interfaces/DGSMStabDAMInterface.cs =================================================================== diff -u --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Interfaces/DGSMStabDAMInterface.cs (revision 0) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Interfaces/DGSMStabDAMInterface.cs (revision 330) @@ -0,0 +1,145 @@ +// 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.Runtime.InteropServices; +using System.Text; + +namespace Deltares.DamEngine.Calculators.Interfaces +{ + public class DGSMStabDAMInterface : DgsStandardDllInterface + { + + public struct LegacyCoordinate + { + public double x; + public double z; + } + + private const string DllFileName = @"DGSMStabDAM.dll"; + + [DllImport(DllFileName)] + static extern int GetDamLicenseType(); + [DllImport(DllFileName)] + static extern int GetDamLiveLicenseType(); + [DllImport(DllFileName)] + static extern int DllGetVersion(out DllVersionInfoStructure dllVersionInfoStructure); + [DllImport(DllFileName)] + static extern string GetDescription(StringBuilder errorMessage, ref int bufferSize); + [DllImport(DllFileName)] + static extern int GetErrorMessage(StringBuilder errorMessage, ref int bufferSize); + [DllImport(DllFileName)] + static extern int CreateMStabProject(string inputXmlString); + [DllImport(DllFileName)] + static extern int ConvertGeometry2DTo1D(string inputXML, StringBuilder outputXML, ref int bufferSize); + [DllImport(DllFileName)] + static extern int CreateGeometry2DData(string inputXML, StringBuilder outputXML, ref int bufferSize); + [DllImport(DllFileName)] + static extern double CalculatePipingLength(int pointCount, ref LegacyCoordinate[] headLinePoints); + + + /// + /// Gets the type of the license for DAM. + /// + /// + public int DamLicenseType() + { + return (GetDamLicenseType()); + } + + /// + /// Gets the type of the license for DAMLive. + /// + /// + public int DamLiveLicenseType() + { + return (GetDamLiveLicenseType()); + } + + /// + /// Gets DllVersion + /// + /// version as string + new public string GetDllVersion() + { + DllVersionInfoStructure dllInfo; + var returnValue = DllGetVersion(out dllInfo); + return dllInfo.DwBuildNumber.ToString(); + } + + /// + /// Create ProjectFile for MStab + /// + /// Error number + public int CreateProjectFile(string inputXmlString) + { + return (CreateMStabProject(inputXmlString)); + } + + /// + /// returns ErrorMessage + /// + /// Error as string + new public string ErrorMessage() + { + const int maxErrorMessageLength = 50; + int errorMessageLength = maxErrorMessageLength; + var errorMessage = new StringBuilder(maxErrorMessageLength); + int returnCode = GetErrorMessage(errorMessage, ref errorMessageLength); + if (returnCode == DllErrorOutputBufferTooSmall) + { + errorMessage = new StringBuilder(errorMessageLength); + returnCode = GetErrorMessage(errorMessage, ref errorMessageLength); + } + if (returnCode == DllErrorNone) + { + return errorMessage.ToString(); + } + else + { + return "Unknow error"; + } + } + + /// + /// converts 2D geometry to 1D + /// + /// Error as integer + public int Geometry2DTo1DConversion(string inputXML, StringBuilder outputXML, ref int bufferSize) + { + return (ConvertGeometry2DTo1D(inputXML, outputXML, ref bufferSize)); + } + + public int CreateGeometry2DDataFromGeometry2D(string inputXML, StringBuilder outputXML, ref int bufferSize) + { + return (CreateGeometry2DData(inputXML, outputXML, ref bufferSize)); + } + + /// + /// calculates the pipinglength + /// + /// pipinglength as double + public double PipingLengthCalculation(int pointCount, ref LegacyCoordinate[] headLinePoints) + { + return (CalculatePipingLength(pointCount, ref headLinePoints)); + } + + } +} Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityServiceAgentException.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityServiceAgentException.cs (.../Deltares.DamEngine.Controllers/StabilityServiceAgentException.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityServiceAgentException.cs (.../Deltares.DamEngine.Calculators/Stability/StabilityServiceAgentException.cs) (revision 330) @@ -21,7 +21,7 @@ using System; -namespace Deltares.DamEngine.Controllers +namespace Deltares.DamEngine.Calculators.Stability { public class StabilityServiceAgentException : Exception { Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment Regional/UpliftRWEvaluator.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment Regional/UpliftRWEvaluator.cs (.../Deltares.DamEngine.Data/RWScenarios/UpliftRWEvaluator.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment Regional/UpliftRWEvaluator.cs (.../Deltares.DamEngine.Calculators/Dikes Assessment Regional/UpliftRWEvaluator.cs) (revision 330) @@ -21,10 +21,13 @@ using System; using System.Collections.Generic; +using Deltares.DamEngine.Calculators.PlLinesCreator; +using Deltares.DamEngine.Calculators.Uplift; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.PlLines; +using Deltares.DamEngine.Data.RWScenarios; -namespace Deltares.DamEngine.Data.RWScenarios +namespace Deltares.DamEngine.Calculators.Dikes_Assessment_Regional { public class UpliftRWEvaluator : RWEvaluator { @@ -91,14 +94,14 @@ plLinesCreator.IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true; // for stability this must set to true plLinesCreator.PlLineOffsetBelowDikeTopAtRiver = location.PlLineOffsetBelowDikeTopAtRiver; plLinesCreator.PlLineOffsetBelowDikeTopAtPolder = location.PlLineOffsetBelowDikeTopAtPolder; - plLinesCreator.SoilBaseDB = null; // soilbase; plLinesCreator.DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(); plLinesCreator.IsUseOvenDryUnitWeight = (dikeDrySensitivity == DikeDrySensitivity.Dry); plLinesCreator.IsHydraulicShortcut = (hydraulicShortcutType == HydraulicShortcutType.HydraulicShortcut); plLinesCreator.XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin; - PLLines plLines = plLinesCreator.CreateAllPLLines(location); - return plLines; +// PLLines plLines = plLinesCreator.CreateAllPLLines(location); +// return plLines; ##Bka + return null; } /// @@ -132,7 +135,6 @@ SurfaceLine = location.LocalXZSurfaceLine2, SoilProfile = soilGeometry.SoilProfile, SoilGeometry2DName = null, - SoilBaseDB = null, //soilbase, DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), PLLines = CreatePLLines(), IsUseOvenDryUnitWeight = (dikeDrySensitivity == DikeDrySensitivity.Dry), Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityServiceAgent.cs =================================================================== diff -u -r303 -r330 --- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityServiceAgent.cs (.../Deltares.DamEngine.Controllers/StabilityServiceAgent.cs) (revision 303) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Stability/StabilityServiceAgent.cs (.../Deltares.DamEngine.Calculators/Stability/StabilityServiceAgent.cs) (revision 330) @@ -25,13 +25,14 @@ using System.IO; using System.Text; using System.Threading; -using System.Threading.Tasks; +using Deltares.DamEngine.Calculators.General; +using Deltares.DamEngine.Calculators.Interfaces; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.Results; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Standard.Language; -namespace Deltares.DamEngine.Controllers +namespace Deltares.DamEngine.Calculators.Stability { /// /// Defines the service agent which is responsible for delegating calls @@ -388,7 +389,7 @@ }; - Parallel.KillOnAbort(process); + General.Parallel.KillOnAbort(process); process.Start();