Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/WaterpressureInterpolationModel.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/WaterpressureInterpolationModel.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/WaterpressureInterpolationModel.cs (revision 334)
@@ -0,0 +1,41 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Shear Strength model type enumerator
+ ///
+ public enum WaterpressureInterpolationModel
+ {
+
+ ///
+ /// Automatic interpolation
+ ///
+ Automatic=1,
+
+ ///
+ /// Hydrostatic interpolation
+ ///
+ Hydrostatic=2
+
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/StabilityResultTypes.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/StabilityResultTypes.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/StabilityResultTypes.cs (revision 334)
@@ -0,0 +1,89 @@
+// 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 Deltares.DamEngine.Data.Geotechnics;
+
+namespace Deltares.DamEngine.Data.General.Results
+{
+ public struct MStabResults
+ {
+ public MStabResultsSingleZone zone1;
+ public MStabResultsSingleZone? zone2;
+ public string CalculationName;
+ public string CalculationSubDir;
+ public int IterationNumber;
+
+ public void Init()
+ {
+ zone1 = new MStabResultsSingleZone();
+ zone1.Init();
+ zone2 = new MStabResultsSingleZone();
+ zone2.Value.Init();
+ }
+ }
+
+ public struct MStabResultsSingleZone
+ {
+ public double safetyFactor;
+ public double circleSurfacePointLeftXCoordinate;
+ public double circleSurfacePointRightXCoordinate;
+ public double entryPointXCoordinate;
+ public double exitPointXCoordinate;
+ public double beta;
+ public void Init()
+ {
+ safetyFactor = 0.0;
+ circleSurfacePointLeftXCoordinate = 0.0;
+ circleSurfacePointRightXCoordinate = 0.0;
+ entryPointXCoordinate = 0.0;
+ exitPointXCoordinate = 0.0;
+ beta = 0.0;
+ }
+ }
+
+ public struct NonWaterRetainingObjectResults
+ {
+ public string NwoId;
+ public double LocationXrdStart;
+ public double LocationYrdStart;
+ public double LocationZrdStart;
+ public double LocationXrdEnd;
+ public double LocationYrdEnd;
+ public double LocationZrdEnd;
+ public MStabResults MStabResults;
+ public SurfaceLine2 AdaptedSurfaceLine;
+ public SoilGeometryProbability SoilProfileProbability;
+ public void Init()
+ {
+ NwoId = "";
+ MStabResults = new MStabResults();
+ MStabResults.Init();
+ LocationXrdStart = 0.0;
+ LocationYrdStart = 0.0;
+ LocationZrdStart = 0.0;
+ LocationXrdEnd = 0.0;
+ LocationYrdEnd = 0.0;
+ LocationZrdEnd = 0.0;
+ AdaptedSurfaceLine = null;
+ }
+
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/PlLines/PLLines.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/PlLines/PLLines.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/PlLines/PLLines.cs (revision 334)
@@ -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.Collections.Generic;
+
+namespace Deltares.DamEngine.Data.General.PlLines
+{
+ public class PLLines
+ {
+ IDictionary lines;
+ public PLLines()
+ {
+ lines = new Dictionary();
+ foreach (PLLineType plLineType in PLLineType.GetValues(typeof(PLLineType)))
+ {
+ this.Lines[plLineType] = new PLLine();
+ }
+ }
+
+ public IDictionary Lines
+ {
+ get { return this.lines; }
+ private set { this.lines = value; }
+ }
+ public int PLLineCount { get { return PLLineType.GetValues(typeof(PLLineType)).GetLength(0); } }
+
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/General/DamProjectCalculatorCsvExportDataBuilder.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/General/DamProjectCalculatorCsvExportDataBuilder.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/General/DamProjectCalculatorCsvExportDataBuilder.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Calculators/Properties/AssemblyInfo.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/Properties/AssemblyInfo.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/Properties/AssemblyInfo.cs (revision 334)
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Deltares.DamEngine.Calculators")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Deltares")]
+[assembly: AssemblyProduct("Deltares.DamEngine.Calculators")]
+[assembly: AssemblyCopyright("Copyright © Deltares 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("952e82dc-2107-4f5c-b1c7-327fceaa0cdd")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("17.1.0.0")]
+[assembly: AssemblyFileVersion("17.1.0.0")]
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/General/Context.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/General/Context.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/General/Context.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs (revision 334)
@@ -0,0 +1,202 @@
+// 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.Xml.Serialization;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Standard.Language;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// 1D Soil Layer Object
+ ///
+ public class SoilLayer1D : SoilLayer, ISoilProfileProvider, ICloneable, IComparable
+ {
+ ///
+ /// Function delegate to get layer above/beneath via the 1D Profile
+ ///
+ /// The layer.
+ ///
+ protected delegate SoilLayer1D LayerGetFunction(SoilLayer1D layer);
+
+ private SoilProfile1D soilProfile;
+ private double topLevel;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SoilLayer1D()
+ {
+ Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSoilLayer1D");
+ }
+
+ ///
+ /// Initializes a new instance of the class, using given soil and topLevel.
+ ///
+ /// The soil.
+ /// The top level.
+ public SoilLayer1D(Soil soil, double topLevel)
+ : this()
+ {
+ Soil = soil;
+ this.topLevel = topLevel;
+ }
+
+ ///
+ /// Gets or sets the toplevel of the layer
+ ///
+ public virtual double TopLevel
+ {
+ get
+ {
+ return topLevel;
+ }
+ set
+ {
+ // don't do anything if top is already value
+ if (Math.Abs(value - topLevel) > GeometryConstants.Accuracy)
+ {
+ topLevel = value;
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the bottom level of the layer
+ ///
+ ///
+ /// The bottom level.
+ ///
+ [XmlIgnore]
+ public virtual double BottomLevel
+ {
+ get
+ {
+ return SoilProfile == null ? 0d : SoilProfile.GetBottomLevel(this);
+ }
+ set
+ {
+ // don't do anything if bottom is already value
+ if (Math.Abs(value - BottomLevel) > GeometryConstants.Accuracy)
+ {
+ var layerBelow = LayerBelow();
+ if (layerBelow != null)
+ {
+ layerBelow.topLevel = value;
+ }
+ else if (SoilProfile != null)
+ {
+ SoilProfile.BottomLevel = value;
+ }
+
+ if (SoilProfile != null && value < SoilProfile.BottomLevel)
+ {
+ SoilProfile.BottomLevel = value;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets the distance between bottom and top.
+ ///
+ ///
+ /// The height.
+ ///
+ [Translation("LayerHeight")]
+ public double Height
+ {
+ get
+ {
+ return TopLevel - BottomLevel;
+ }
+ }
+
+ /// Gets or sets the soil profile.
+ /// The soil profile is set automatically by the soil layers list in SoilProfile1D
+ [XmlIgnore]
+ public SoilProfile1D SoilProfile
+ {
+ get
+ {
+ return soilProfile;
+ }
+ set
+ {
+ soilProfile = value;
+ }
+ }
+
+ ///
+ /// Clones this instance.
+ ///
+ /// Clone of this instance
+ public virtual object Clone()
+ {
+ var clone = new SoilLayer1D();
+ clone.Assign(this);
+ return clone;
+ }
+
+ ///
+ /// Returns the Layer below.
+ ///
+ /// layer below
+ private SoilLayer1D LayerBelow()
+ {
+ return SoilProfile.GetLayerBelow(this);
+ }
+
+ ///
+ /// Assigns the specified layer.
+ ///
+ /// The layer.
+ public void Assign(SoilLayer1D layer)
+ {
+ Name = layer.Name;
+ TopLevel = layer.TopLevel;
+ Soil = layer.Soil;
+ IsAquifer = layer.IsAquifer;
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ ///
+ /// Sorting will be applied by the mot uplift layer first
+ ///
+ /// Other soil layer
+ /// Comparable indication
+ public int CompareTo(SoilLayer1D other)
+ {
+ return - TopLevel.CompareTo(other.TopLevel);
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Validator.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Validator.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Validator.cs (revision 334)
@@ -0,0 +1,158 @@
+// 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.Geometry;
+using Deltares.DamEngine.Data.Standard;
+using Deltares.DamEngine.Data.Standard.Language;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Validator for .
+ ///
+ public class SurfaceLine2Validator
+ {
+ ///
+ /// Performs all validation checks for a surfaceline.
+ ///
+ /// The surfaceline being evaluated.
+ /// The collection of validation results.
+ public IEnumerable Validate(SurfaceLine2 surfaceline)
+ {
+ return ValidateGeometryPointsAreOrdered(surfaceline)
+ .Concat(ValidateCharacteristicPointsAreOrdered(surfaceline))
+ .Concat(ValidateDikeShape(surfaceline));
+ }
+
+ ///
+ /// Checks if all instances in
+ /// are ordered on ascending X.
+ ///
+ /// The surfaceline being evaluated.
+ /// The collection of validation results.
+ public IEnumerable ValidateGeometryPointsAreOrdered(SurfaceLine2 surfaceline)
+ {
+ if (!ArePointsAscending(surfaceline))
+ {
+ yield return new ValidationResult(ValidationResultType.Error, this.Translate("SurfacePointsNotAscending"),
+ surfaceline, surfaceline.GetMemberName(sl => sl.Geometry), "");
+ }
+ }
+
+ ///
+ /// Checks if all characteristic points that require proper ordering based on X coordinate
+ /// are indeed properly ordered.
+ ///
+ /// The surfaceline being evaluated.
+ /// The collection of validation results.
+ public IEnumerable ValidateCharacteristicPointsAreOrdered(SurfaceLine2 surfaceline)
+ {
+ if (!AreAllCharacteristicPointsXCoordinatesAscending(surfaceline))
+ {
+ yield return new ValidationResult(ValidationResultType.Error, this.Translate("ChartPointsNotAscending"),
+ surfaceline, surfaceline.GetMemberName(sl => sl.CharacteristicPoints), "");
+ }
+ }
+
+ ///
+ /// Ares all characteristic points x coordinates ascending.
+ ///
+ /// The line.
+ ///
+ public static bool AreAllCharacteristicPointsXCoordinatesAscending(SurfaceLine2 line)
+ {
+ var points = line.GetCharacteristicPointsRequiringAscendingX().ToArray();
+ return AreGeometryPointsXCoordinatesAscending(points);
+ }
+
+ ///
+ /// Checks if the shape of the dike is proper.
+ ///
+ /// The surfaceline being evaluated.
+ /// The collection of validation results.
+ private IEnumerable ValidateDikeShape(SurfaceLine2 surfaceline)
+ {
+ if (!AreAllCharacteristicPointsInCorrectShape(surfaceline))
+ {
+ yield return new ValidationResult(ValidationResultType.Error,
+ this.Translate("ImproperDikeShape"), surfaceline);
+ }
+ }
+
+ ///
+ /// Determines whether all characteristic points are in correct shape.
+ ///
+ /// true if all characteristic are in correct shape, otherwise false
+ public static bool AreAllCharacteristicPointsInCorrectShape(SurfaceLine2 line)
+ {
+ // when there are no points to check, make sure true is returned.
+ var result = true;
+
+ if (line.IsDefined(CharacteristicPointType.DikeToeAtRiver) && line.IsDefined(CharacteristicPointType.DikeTopAtRiver))
+ {
+ result = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).Z < line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z;
+ }
+
+ if (line.IsDefined(CharacteristicPointType.DikeToeAtPolder) && line.IsDefined(CharacteristicPointType.DikeTopAtPolder))
+ {
+ result = result && line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z < line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z;
+ }
+
+ return result;
+ }
+
+ private bool ArePointsAscending(SurfaceLine2 line)
+ {
+ return AreGeometryPointsXCoordinatesAscending(line.Geometry.Points);
+ }
+
+ private static bool AreGeometryPointsXCoordinatesAscending(IList points)
+ {
+ for (int i = 1; i < points.Count; i++)
+ {
+ if (points[i].X < points[i - 1].X + GeometryConstants.Accuracy)
+ {
+ // #Bka: if fact we now should return FALSE immediately but there is a snag. Due to faults with adding characteristic
+ // points to a surface line, some surface lines can have identical points (in Location) but with different
+ // characteristic (e.g. diktop and trafficload combined). These points should use the same refence to the point
+ // but it occurs that TWO fysical (and identical) points are added.
+ // So these points must now be ignored (so identical points must be seen as OK). This is in fact ok for the purpose
+ // of the validation ast the main problem is that points may never give a vertical part in the geometry.
+ if ((Math.Abs(points[i].X - points[i - 1].X) < GeometryConstants.Accuracy) && (Math.Abs(points[i].Z - points[i - 1].Z) < GeometryConstants.Accuracy))
+ {
+ // Make sure points are made identical
+ points[i].X = points[i - 1].X;
+ points[i].Z = points[i - 1].Z;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/PlLines/PLLine.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/PlLines/PLLine.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/PlLines/PLLine.cs (revision 334)
@@ -0,0 +1,129 @@
+// 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 System.Xml.Serialization;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.General.PlLines
+{
+ public class PLLinePoint : GeometryPoint
+ {
+ public PLLinePoint() : this (0, 0) { }
+
+ public PLLinePoint(double aX, double aZ) : base(aX, aZ)
+ {
+ }
+ }
+
+ public class PLLine : PolyLine, ICloneable
+ {
+ private PLLineType plLineType;
+
+ [XmlIgnore]
+ public PLLineType PLLineType
+ {
+ get { return plLineType; }
+ set
+ {
+ plLineType = value;
+ PLLineTypeSpecified = true;
+ }
+ }
+
+ [XmlIgnore]
+ public bool PLLineTypeSpecified { get; private set; }
+
+
+ public bool IsPhreatic { get; set; }
+
+ public int BoundaryLayer { get; set; }
+
+ public PLLine Clone()
+ {
+ PLLine plLine = new PLLine() { IsPhreatic = this.IsPhreatic, BoundaryLayer = this.BoundaryLayer };
+ foreach (PLLinePoint point in this.Points)
+ {
+ PLLinePoint newPoint = new PLLinePoint() { X = point.X, Y = point.Y, Z = point.Z };
+ plLine.Points.Add(newPoint);
+ }
+ return plLine;
+ }
+
+ ///
+ /// Gets the points in the segment between starting x and ending x
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable GetPointSegmentBetween(double startX, double endX)
+ {
+ if (endX < startX)
+ throw new ArgumentException("End value is smaller then the start value");
+
+ return from point in this.PointsOrderdByX
+ where point != null && (point.X > startX && point.X < endX)
+ orderby point.X ascending
+ select point;
+ }
+
+ ///
+ /// Determines whether the given point is above, beneath or on the surfaceline.
+ ///
+ ///
+ ///
+ public PLLinePointPositionXzType PositionXzOfPointRelatedToPLLine(GeometryPoint point)
+ {
+ // if point is out of scope of the surface line, return beyond
+ if ((point.X < points[0].X) || (point.X > points[points.Count - 1].X))
+ return PLLinePointPositionXzType.BeyondPLLine;
+
+ double z = ZFromX(point.X);
+ if (Math.Abs(point.Z - z) < GeometryPoint.Precision)
+ {
+ return PLLinePointPositionXzType.OnPLLine;
+ }
+ else
+ {
+ if (point.Z > z)
+ {
+ return PLLinePointPositionXzType.AbovePLLine;
+ }
+ else
+ {
+ return PLLinePointPositionXzType.BelowPLLine;
+ }
+ }
+ }
+
+ private IEnumerable PointsOrderdByX
+ {
+ get { return this.Points.OrderBy(p => p.X); }
+ }
+
+ }
+
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (revision 334)
@@ -0,0 +1,900 @@
+// 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.Standard;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Classifications of an objected with regards to a geometric line in the XZ-plane.
+ ///
+ public enum RelativeXzPosition
+ {
+ ///
+ /// Indicates that the object is considered 'on' the geometric line.
+ ///
+ OnGeometricLine,
+ ///
+ /// Indicates that the object is considered 'above' the geometric line (object Z
+ /// coordinate higher than that of the line).
+ ///
+ AboveGeometricLine,
+ ///
+ /// Indicates that the object is considered 'below' the geometric line (object Z
+ /// coordinates lower than that of the line).
+ ///
+ BelowGeometricLine,
+ ///
+ /// Indicates that the object is considered 'outside the scope' of the geometric line.
+ ///
+ BeyondGeometricLine
+ }
+
+ ///
+ /// Type of extrapolation
+ ///
+ public enum ExtraPolationMode
+ {
+ ///
+ /// No extrapolation should be used.
+ ///
+ Beyond,
+ ///
+ /// Used constant (0th order) extrapolation at the extremes.
+ ///
+ Horizontal
+ }
+
+ ///
+ /// Collection of points (X,Z) in world coordinates used for describing Surface lines
+ ///
+ public class GeometryPointString : GeometryObject
+ {
+ ///
+ /// Matching distance where a point within this range is considered on the same point.
+ ///
+ private const double epsilon = GeometryConstants.Accuracy;
+ private readonly List points = new List();
+ ///
+ /// The calculate points as protected field (to be able to prevent recursive calls to CalcPoints)
+ ///
+ protected readonly List calcPoints = new List();
+ private bool isFrozen;
+ private bool hasNaNx;
+ private double frozenMaxZ = double.NaN;
+
+ // sortedPoints must never be used outside this class. Either the GPS concerned must have sorted points but then they already are
+ // (eg. surfaceline, headline) or they may be unsorted in which case using the sorted list in other classes leads to errors (eg.
+ // geometrysurfaces, waternetlines)
+ private List sortedPoints;
+
+ ///
+ /// The calculate points (to be used in calcualtion instead of Points for better performance)
+ ///
+ public virtual List CalcPoints
+ {
+ get
+ {
+ return calcPoints;
+ }
+ }
+
+ ///
+ /// Freezes this instance.
+ ///
+ public void Freeze()
+ {
+ if (!isFrozen)
+ {
+ sortedPoints = new List(calcPoints.Count);
+ foreach (Point2D point in calcPoints)
+ {
+ sortedPoints.Add(point);
+ hasNaNx = hasNaNx | double.IsNaN(point.X);
+ frozenMaxZ = Math.Max(frozenMaxZ, point.Z);
+ }
+ sortedPoints.Sort();
+ }
+ isFrozen = true;
+ }
+
+ ///
+ /// List of points that describe the physical surface line or surface.
+ ///
+ ///
+ /// The points.
+ ///
+ public virtual IList Points
+ {
+ get
+ {
+ return points;
+ }
+ }
+
+ ///
+ /// Gets the at the specified index.
+ ///
+ ///
+ /// The .
+ ///
+ /// The index.
+ /// When less
+ /// than zero or is greater or equals to .
+ public Point2D this[int index]
+ {
+ get
+ {
+ return calcPoints[index];
+ }
+ }
+
+ ///
+ /// Gets the count of the points.
+ ///
+ ///
+ /// The count.
+ ///
+ public int Count
+ {
+ get
+ {
+ return calcPoints.Count;
+ }
+ }
+
+
+ ///
+ /// Clones this object except the points
+ ///
+ ///
+ public virtual GeometryPointString Clone()
+ {
+ var clone = new GeometryPointString();
+ this.CloneProperties(clone); // exludes the points !
+ clone.Points.Clear();
+ foreach (var point in Points)
+ {
+ clone.Points.Add(new GeometryPoint(point));
+ }
+ clone.SyncCalcPoints();
+ return clone;
+ }
+
+ ///
+ /// Gets the minimum z.
+ /// Note: CalcPoints must be used instead of calcPoints as otherwise unclear behaviour of Linq spoils the result
+ /// Change back to calcPoints and Benchmark4_01l in the WaternetCreatorTests will fail!
+ ///
+ ///
+ public double GetMinZ()
+ {
+ return CalcPoints.Any()
+ ? CalcPoints.Min(p => p.Z)
+ : double.NaN;
+ }
+
+ ///
+ /// Gets the maximum z.
+ /// Note: CalcPoints must be used instead of calcPoints as otherwise unclear behaviour of Linq spoils the result
+ /// Change back to calcPoints and Benchmark4_01l in the WaternetCreatorTests will fail!
+ ///
+ ///
+ public double GetMaxZ()
+ {
+ if (isFrozen) return frozenMaxZ;
+ return CalcPoints.Any()
+ ? CalcPoints.Max(p => p.Z)
+ : double.NaN;
+ }
+
+ ///
+ /// The minimal X value among .
+ /// Note: CalcPoints must be used instead of calcPoints as otherwise unclear behaviour of Linq spoils the result
+ /// Change back to calcPoints and Benchmark4_01l in the WaternetCreatorTests will fail!
+ ///
+ /// The minimal X value or in case there are no points.
+ public double GetMinX()
+ {
+ if (isFrozen && !hasNaNx) return sortedPoints[0].X;
+ return CalcPoints.Any(p => !double.IsNaN(p.X))
+ ? CalcPoints.Where(p => !double.IsNaN(p.X)).Min(p => p.X)
+ : double.NaN;
+ }
+
+ ///
+ /// Gets the maximum x.
+ /// Note: CalcPoints must be used instead of calcPoints as otherwise unclear behaviour of Linq spoils the result
+ /// Change back to calcPoints and Benchmark4_01l in the WaternetCreatorTests will fail!
+ ///
+ ///
+ public double GetMaxX()
+ {
+ if (isFrozen && !hasNaNx) return sortedPoints[sortedPoints.Count - 1].X;
+ return CalcPoints.Any(p => !double.IsNaN(p.X))
+ ? CalcPoints.Where(p => !double.IsNaN(p.X)).Max(p => p.X)
+ : double.NaN;
+ }
+
+ ///
+ /// Finds all vertical XZ intersections with this geometric point string, returning
+ /// the highest value among the intersections.
+ ///
+ /// X coordinate
+ ///
+ /// The z value determined by or
+ /// when is empty.
+ ///
+ ///
+ /// Uses constant extrapolation and linear interpolation.
+ ///
+ public double GetZAtUnsortedX(double x)
+ {
+ if (calcPoints.Count > 0)
+ {
+ var verticalLineAtX = new Line(new Point2D {X = x, Z= GetMaxZ()},
+ new Point2D { X = x, Z = GetMinZ() });
+ if (Math.Abs(verticalLineAtX.BeginPoint.Z - verticalLineAtX.EndPoint.Z) < GeometryConstants.Accuracy)
+ {
+ verticalLineAtX.BeginPoint.Z += 1.0;
+ verticalLineAtX.EndPoint.Z -= 1.0;
+ }
+ var intersectionPoints = IntersectionPointsXzWithLineXz(verticalLineAtX);
+ if (intersectionPoints.Count != 0)
+ {
+ return intersectionPoints.Max(gp => gp.Z);
+ }
+
+ // Remain consistent with GetZAtX, do constant extrapolation:
+ double zAtX;
+ if (DoConstantExtrapolationXz(x, out zAtX))
+ {
+ return zAtX;
+ }
+ }
+ return double.NaN;
+ }
+
+ ///
+ /// Retrieves the Z value for the given x.
+ ///
+ /// X coordinate
+ ///
+ /// The z value determined by or
+ /// when is empty.
+ ///
+ ///
+ /// Uses constant extrapolation and linear interpolation.
+ ///
+ public virtual double GetZatX(double x)
+ {
+ if (calcPoints.Any())
+ {
+ double zAtX;
+ if (DoConstantExtrapolationXz(x, out zAtX))
+ {
+ return zAtX;
+ }
+ }
+ for (int i = 0; i < calcPoints.Count - 1; i++)
+ {
+ var current = calcPoints[i];
+ var next = calcPoints[i + 1];
+
+ var leftOffset = x - current.X;
+ var rightOffset = next.X - x;
+
+ if (Math.Abs(leftOffset) < epsilon)
+ {
+ return current.Z;
+ }
+ if (Math.Abs(rightOffset) < epsilon)
+ {
+ return next.Z;
+ }
+ if (leftOffset >= 0 && rightOffset >= 0)
+ {
+ var fraction = leftOffset / (leftOffset + rightOffset);
+
+ return (1.0 - fraction) * current.Z + fraction * next.Z;
+ }
+ }
+
+ return Double.NaN;
+ }
+
+ ///
+ /// Gets the z at x starting from index i in the point list.
+ /// This is only meant as a fast(er) version for GetZAtX for lists that are sorted by X, so use with care.
+ ///
+ /// The x.
+ /// The i.
+ ///
+ public virtual double GetZatX(double x, ref int i)
+ {
+ for (; i < calcPoints.Count - 1; i++)
+ {
+ var current = calcPoints[i];
+ var leftOffset = x - current.X;
+ var next = calcPoints[i + 1];
+ var rightOffset = next.X - x;
+
+ if (leftOffset < epsilon)
+ {
+ return current.Z;
+ }
+ if (rightOffset >= epsilon)
+ {
+ var fraction = leftOffset / (leftOffset + rightOffset);
+ return (1.0 - fraction) * current.Z + fraction * next.Z;
+ }
+ if (i + 1 == calcPoints.Count - 1)
+ {
+ return next.Z;
+ }
+ }
+
+ return Double.NaN;
+ }
+
+ ///
+ /// Gets all z-values at x for a line.
+ ///
+ /// The x.
+ ///
+ public List GetAllZatXForLine(double x)
+ {
+ return GetAllZatX(x, false);
+ }
+
+ ///
+ /// Gets all z values at x for a surface.
+ ///
+ /// The x.
+ ///
+ public List GetAllZatXForSurface(double x)
+ {
+ return GetAllZatX(x, true);
+ }
+
+ ///
+ /// Finds the first intersection of the line with a given horizontal line.
+ ///
+ /// The height level of the horizontal line.
+ /// Optional: Discard intersections whose X value is less then
+ /// or equal to this value.
+ /// The first intersection point matching the criteria.
+ ///
+ public double GetXatZ(double z, double xmin = Double.MinValue)
+ {
+ return GetXatZStartingAt(0, z, xmin);
+ }
+
+ ///
+ /// Finds the first intersection of the line with a given horizontal line.
+ ///
+ /// Start considering instances from
+ /// starting from this index.
+ /// The height level of the horizontal line.
+ /// Optional: Discard intersections whose X value is less then
+ /// or equal to this value.
+ /// The first intersection point matching the criteria.
+ ///
+ public double GetXatZStartingAt(int start, double z, double xmin = Double.MinValue)
+ {
+ for (int i = start; i < calcPoints.Count - 1; i++)
+ {
+ var current = calcPoints[i];
+ var next = calcPoints[i + 1];
+
+ if (IsSegmentNotCrossingZ(z, current, next)) // Performance micro-optimization
+ {
+ continue;
+ }
+
+ var x = GetXIntersectingZ(z, current, next);
+ if (x > xmin)
+ {
+ return x;
+ }
+ }
+
+ return Double.NaN;
+ }
+
+ ///
+ /// Gets the points at x.
+ ///
+ /// The x.
+ ///
+ public IEnumerable GetPointsAtX(double x)
+ {
+ return (from Point2D point in calcPoints
+ where point.X.AlmostEquals(x, GeometryPoint.Precision)
+ select point);
+ }
+
+ ///
+ /// Gets the point at.
+ ///
+ /// The x.
+ /// The z.
+ ///
+ public Point2D GetPointAt(double x, double z)
+ {
+ return calcPoints.FirstOrDefault(
+ point => point.X.AlmostEquals(x, GeometryPoint.Precision) &&
+ point.Z.AlmostEquals(z, GeometryPoint.Precision));
+ }
+
+ //#Bka: this should never be 1 method! Split it into 2 methods
+ // It is used for sliplanes only and therefor uses Points instead of calcPoints
+ ///
+ /// Adds the or remove list object.
+ ///
+ /// a point.
+ /// if set to true [a to add].
+ /// a index.
+ public virtual void AddOrRemoveListObject(object aPoint, bool aToAdd, int aIndex)
+ {
+ var point = aPoint as GeometryPoint;
+ if (point == null)
+ {
+ return;
+ }
+
+ if (aToAdd)
+ {
+ Points.Insert(aIndex, point); //#bka what happens if index already exists? what if point exists? What if both???
+ }
+ else
+ {
+ if (Points.Contains(point))
+ {
+ Points.Remove(point);
+ }
+ }
+ }
+
+ ///
+ /// Returns ALL intersection points that are found, including the double ones as the number of points can be relevant!
+ ///
+ ///
+ ///
+ public IList IntersectionPointsXzWithLineXzWithAllPoints(Line line)
+ {
+ return IntersectionPointsWithLineCore(line, true);
+ }
+
+ ///
+ /// Returns the UNIQUE intersectionpoints (so can not be used where number of interscections is relevant)
+ ///
+ ///
+ ///
+ public IList IntersectionPointsXzWithLineXz(Line line)
+ {
+ return IntersectionPointsWithLineCore(line, false);
+ }
+
+ private IList IntersectionPointsXzClosedStringWithLineXz(Line line)
+ {
+ IList intersectionPointsWithLine = IntersectionPointsXzWithLineXz(line);
+
+ // close the poly line
+ if (calcPoints.Count > 0)
+ {
+ DoIntersectAndAddToCollection(line, calcPoints[calcPoints.Count - 1], calcPoints[0],
+ intersectionPointsWithLine, false);
+ }
+
+ return intersectionPointsWithLine;
+ }
+
+ ///
+ /// Find intersection (xz-plane) from this surface with another surface
+ /// or phratic line
+ ///
+ ///
+ ///
+ /// Considers all in to
+ /// such that they describe a closed loop.
+ ///
+ public IList ClosedGeometryIntersectionXzPointsWithGeometryPointList(IList list)
+ {
+ return IntersectWithPointsListCore(list, true);
+ }
+
+ ///
+ /// Finds all intersections in the XZ-plane the given list.
+ ///
+ /// The list.
+ ///
+ ///
+ ///
+ private List IntersectionXzPointsWithGeometryPointList(IList list)
+ {
+ return IntersectWithPointsListCore(list, false);
+ }
+
+ ///
+ /// Finds all intersections in the XZ-plane the given .
+ ///
+ /// The geometry point string.
+ ///
+ ///
+ public List IntersectionXzPointsWithGeometryString(GeometryPointString externalSurface)
+ {
+ return IntersectionXzPointsWithGeometryPointList(externalSurface.CalcPoints);
+ }
+
+ ///
+ /// Sorts the points by x ascending (only to be used for Surface lines).
+ ///
+ public virtual void SortPointsByXAscending()
+ {
+ calcPoints.Sort();
+ }
+
+ ///
+ /// Gets a part of the geometry point string defined by a begin and end point
+ ///
+ ///
+ ///
+ ///
+ public GeometryPointString GetPart(double begin, double end)
+ {
+ var part = new GeometryPointString();
+ bool filling = false;
+ bool filled = false;
+
+ for (int i = 0; i < calcPoints.Count; i++)
+ {
+ if (!filling && !filled)
+ {
+ filling = calcPoints[i].X >= begin - epsilon;
+ }
+ else
+ {
+ filled = calcPoints[i].X >= end - epsilon;
+ if (filled)
+ {
+ filling = false;
+ }
+ }
+
+ if (filling)
+ {
+ part.calcPoints.Add(calcPoints[i]);
+ }
+ }
+
+ var beginPoint = new Point2D(begin, GetZatX(begin));
+ var endPoint = new Point2D(end, GetZatX(end));
+
+ if (part.calcPoints.Count == 0)
+ {
+ part.calcPoints.Add(beginPoint);
+ part.calcPoints.Add(endPoint);
+ }
+
+ if (!part.calcPoints[0].LocationEquals(beginPoint))
+ {
+ part.calcPoints.Insert(0, beginPoint);
+ }
+
+ if (!part.calcPoints[part.calcPoints.Count - 1].LocationEquals(endPoint))
+ {
+ part.calcPoints.Add(endPoint);
+ }
+ SyncPoints();
+ return part;
+ }
+
+ ///
+ /// Removes all double points at a location, if consecutive
+ ///
+ public void CondensePoints()
+ {
+ for (int i = calcPoints.Count - 1; i > 0; i--)
+ {
+ if (calcPoints[i].LocationEquals(calcPoints[i - 1]))
+ {
+ calcPoints.RemoveAt(i);
+ }
+ }
+ }
+
+ ///
+ /// Removes all points which don't influence the shape of the line
+ ///
+ public void RemoveUnnecessaryPoints()
+ {
+ const double slopeTolerance = 1E-10;
+
+ CondensePoints();
+
+ for (int i = calcPoints.Count - 2; i > 1; i--)
+ {
+ // if the slope of the line before the point is equal to the slope after the point, the point can be removed
+ double slopeBefore = (calcPoints[i].Z - calcPoints[i - 1].Z) / (calcPoints[i].X - calcPoints[i - 1].X);
+ double slopeAfter = (calcPoints[i + 1].Z - calcPoints[i].Z) / (calcPoints[i + 1].X - calcPoints[i].X);
+
+ if (Routines2D.AreEqual(slopeBefore, slopeAfter, slopeTolerance))
+ {
+ calcPoints.RemoveAt(i);
+ }
+ }
+ }
+
+ ///
+ /// Gets the surrounding rectangle around the geometry point string
+ ///
+ ///
+ public override GeometryBounds GetGeometryBounds()
+ {
+ if (!Points.Any())
+ {
+ // Sync with calcPoints
+ SyncPoints();
+ // if still no points, then return null
+ if (!Points.Any()) return null;
+ }
+
+ GeometryBounds bounds = Points[0].GetGeometryBounds();
+ for (var i = 1; i < Points.Count; i++)
+ {
+ GeometryPoint point = Points[i];
+
+ bounds.Left = Math.Min(bounds.Left, point.X);
+ bounds.Right = Math.Max(bounds.Right, point.X);
+ bounds.Top = Math.Max(bounds.Top, point.Z);
+ bounds.Bottom = Math.Min(bounds.Bottom, point.Z);
+ }
+
+ return bounds;
+ }
+
+ ///
+ /// Checks if constant extrapolation can be applied, and if so set the Z value.
+ ///
+ /// The evaluated X coordinate.
+ /// Output param: Extrapolated Z value, or
+ /// when no extrapolation is possible.
+ /// True if extrapolation possible; false otherwise.
+ private bool DoConstantExtrapolationXz(double x, out double z)
+ {
+ if (calcPoints.Count > 0)
+ {
+ var first = calcPoints[0];
+ if (x < first.X || Math.Abs(x - first.X) < epsilon)
+ {
+ z = first.Z;
+ return true;
+ }
+
+ var last = calcPoints[calcPoints.Count - 1];
+ if (x > last.X)
+ {
+ z = last.Z;
+ return true;
+ }
+ }
+
+ z = double.NaN;
+ return false;
+ }
+
+ ///
+ /// Can be used for a Line or for a Surface where a surface is supposed to closed.
+ /// In case of a waternet line it is possible
+ /// to have more z values at a give x coor
+ /// Furthermore a z is not needed at al x values
+ ///
+ ///
+ ///
+ ///
+ private List GetAllZatX(double x, bool asSurface)
+ {
+ var result = new List();
+
+ if (calcPoints.Count == 1 && Math.Abs(calcPoints[0].X - x) < epsilon)
+ {
+ result.Add(calcPoints[0].Z);
+ }
+
+ var pointsCount = calcPoints.Count - 1;
+ if (asSurface)
+ {
+ pointsCount = calcPoints.Count;
+ }
+ for (int i = 0; i < pointsCount; i++)
+ {
+ Point2D current;
+ Point2D next;
+ if (i == calcPoints.Count - 1)
+ {
+ current = calcPoints[i];
+ next = calcPoints[0];
+ }
+ else
+ {
+ current = calcPoints[i];
+ next = calcPoints[i + 1];
+ }
+
+ var leftOffset = x - current.X;
+ var rightOffset = next.X - x;
+
+ var matchedWithAPoint = false;
+ if (Math.Abs(leftOffset) < epsilon)
+ {
+ result.Add(current.Z);
+ matchedWithAPoint = true;
+ }
+ if (Math.Abs(rightOffset) < epsilon)
+ {
+ result.Add(next.Z);
+ matchedWithAPoint = true;
+ }
+ if (!matchedWithAPoint)
+ {
+ if (leftOffset > 0 && rightOffset > 0)
+ {
+ var fraction = leftOffset / (leftOffset + rightOffset);
+
+ result.Add((1.0 - fraction) * current.Z + fraction * next.Z);
+ }
+
+ // if both ofsets are negative the waterline goes back
+ if ((leftOffset < 0) && (rightOffset < 0))
+ {
+ var fraction = rightOffset / (rightOffset + leftOffset);
+
+ result.Add((1.0 - fraction) * next.Z + fraction * current.Z);
+ }
+ }
+ }
+
+ return result.Distinct().ToList();
+ }
+
+ private static bool IsSegmentNotCrossingZ(double z, Point2D current, Point2D next)
+ {
+ if (double.IsNaN(z))
+ {
+ return true;
+ }
+
+ var leftOffset = Math.Abs(current.Z - z);
+ var rightOffset = Math.Abs(next.Z - z);
+
+ int currentSign = leftOffset < epsilon ? 0 : Math.Sign(current.Z - z);
+ int nextSign = rightOffset < epsilon ? 0 : Math.Sign(next.Z - z);
+ return currentSign == nextSign && currentSign != 0;
+ }
+
+ private static double GetXIntersectingZ(double z, Point2D current, Point2D next)
+ {
+ var leftOffset = Math.Abs(current.Z - z);
+ if (leftOffset < epsilon)
+ {
+ return current.X;
+ }
+ var rightOffset = Math.Abs(next.Z - z);
+ if (rightOffset < epsilon)
+ {
+ return next.X;
+ }
+
+ var fraction = leftOffset / (leftOffset + rightOffset);
+ return GeneralMathRoutines.LinearInterpolate(current.X, next.X, fraction);
+ }
+
+ private IList IntersectionPointsWithLineCore(Line line, bool allowDuplicates)
+ {
+ var intersectionPointsWithLine = new List();
+
+ for (int pointIndex = 0; pointIndex < calcPoints.Count - 1; pointIndex++)
+ {
+ DoIntersectAndAddToCollection(line, calcPoints[pointIndex], calcPoints[pointIndex + 1],
+ intersectionPointsWithLine, allowDuplicates);
+ }
+ return intersectionPointsWithLine;
+ }
+
+ private static void DoIntersectAndAddToCollection(Line line, Point2D begin, Point2D end, ICollection intersectionPointsWithLine, bool allowDuplicates)
+ {
+ var lineInPoly = new Line
+ {
+ BeginPoint = begin,
+ EndPoint = end
+ };
+ Point2D intersectionPoint = lineInPoly.GetIntersectPointXz(line);
+ if (intersectionPoint != null && (allowDuplicates || NoPointSameXzLocation(intersectionPointsWithLine, intersectionPoint)))
+ {
+ intersectionPointsWithLine.Add(intersectionPoint);
+ }
+ }
+
+ private static bool NoPointSameXzLocation(IEnumerable collection, Point2D point)
+ {
+ return !collection.Any(
+ p => Math.Abs(p.X - point.X) < GeometryConstants.Accuracy &&
+ Math.Abs(p.Z - point.Z) < GeometryConstants.Accuracy);
+ }
+
+ private List IntersectWithPointsListCore(IList list, bool closePointString)
+ {
+ var result = new List();
+ var line = new Line();
+ for (int externalPointIndex = 0; externalPointIndex < list.Count - 1; externalPointIndex++)
+ {
+ line.BeginPoint = list[externalPointIndex];
+ line.EndPoint = list[externalPointIndex + 1];
+
+ result.AddRange(!closePointString
+ ? IntersectionPointsXzWithLineXzWithAllPoints(line)
+ : IntersectionPointsXzClosedStringWithLineXz(line));
+ }
+
+ return result;
+ }
+
+ ///
+ /// Synchronizes the calculation points.
+ ///
+ public void SyncCalcPoints()
+ {
+ calcPoints.Clear();
+ foreach (var geometryPoint in Points)
+ {
+ var p2D = new Point2D
+ {
+ X = geometryPoint.X,
+ Z = geometryPoint.Z
+
+ };
+ calcPoints.Add(p2D);
+ }
+ }
+
+ ///
+ /// Synchronizes the points.
+ ///
+ public void SyncPoints()
+ {
+ points.Clear();
+ foreach (var p2D in calcPoints)
+ {
+ var geometryPoint = new GeometryPoint
+ {
+ X = p2D.X,
+ Z = p2D.Z
+
+ };
+ points.Add(geometryPoint);
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/General/Parallel.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/General/Parallel.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/General/Parallel.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Data/RWScenarios/EvaluationJob.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/EvaluationJob.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/EvaluationJob.cs (revision 334)
@@ -0,0 +1,154 @@
+// 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.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
+{
+ public class EvaluationJob
+ {
+ private string dikeName = "";
+ private List locations = new List();
+ private List failedEvaluatedLocations = new List();
+ private List results = new List();
+ private List schematizationFactorResults = new List();
+
+ public string DikeName
+ {
+ get { return dikeName; }
+ set { dikeName = value; }
+ }
+
+ public List Locations
+ {
+ get { return locations; }
+ set { locations = value; }
+ }
+
+ public List Results
+ {
+ get { return results; }
+ set { results = value; }
+ }
+
+ public List SchematizationFactorResults
+ {
+ get { return schematizationFactorResults; }
+ set { schematizationFactorResults = value; }
+ }
+
+ [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));
+//
+// 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; }
+ set { failedEvaluatedLocations = value; }
+ }
+
+ public void AttachResults(IEnumerable locationJobs)
+ {
+ foreach (LocationJob locationJob in locationJobs)
+ {
+ foreach (Location location in this.locations)
+ {
+ if (locationJob.Location.Name.Equals(location.Name))
+ {
+ if (locationJob.LocationResult == null)
+ {
+ locationJob.LocationResult = new LocationResult();
+ }
+
+ if ((this.locations.IndexOf(location) < 0) || (this.locations.IndexOf(location) >= this.results.Count))
+ {
+ var failedRes = new RWScenariosResult();
+ failedRes.CalculationResult = CalculationResult.UnexpectedError;
+ locationJob.LocationResult.RWScenariosResult = failedRes;
+ }
+ else
+ {
+ locationJob.LocationResult.RWScenariosResult = this.results[this.locations.IndexOf(location)];
+ }
+
+
+ foreach (RWScenarioResult scenarioResult in locationJob.LocationResult.RWScenariosResult.RWScenarioResults)
+ {
+ foreach (RWScenarioProfileResult scenarioProfileResult in scenarioResult.RWScenarioProfileResults)
+ {
+ scenarioProfileResult.Location = locationJob.Location;
+ }
+ }
+
+
+ if ((this.locations.IndexOf(location) < 0) || (this.locations.IndexOf(location) >= this.results.Count))
+ {
+ // var failedRes = new RWSchematizationFactorsResult();
+ // failedRes.SchematizationFactorResults. = CalculationResult.UnexpectedError;
+ // locationJob.LocationResult.RWScenariosResult = failedRes;
+ }
+ else
+ {
+ if (schematizationFactorResults.Count > this.locations.IndexOf(location))
+ {
+ locationJob.LocationResult.SchematizationFactorsResult =
+ schematizationFactorResults[this.locations.IndexOf(location)];
+ }
+ }
+
+ if (locationJob.LocationResult.SchematizationFactorsResult != null)
+ {
+ foreach (var schematizationFactorResult in locationJob.LocationResult.SchematizationFactorsResult.SchematizationFactorResults)
+ {
+ schematizationFactorResult.Location = locationJob.Location;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Group.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Group.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Group.cs (revision 334)
@@ -0,0 +1,235 @@
+// 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 System.Xml.Serialization;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.General.Sensors
+{
+ public class Group
+ {
+ ///
+ /// Holds a reference to the set of selected sensors
+ ///
+ private readonly HashSet sensors;
+ private List pickSensors;
+ private int id;
+
+ ///
+ /// Holds a reference to a set of relative loctions along the profile
+ ///
+ private readonly IDictionary relativeLocationAlongProfileDictionary;
+
+ public Group()
+ {
+ sensors = new HashSet();
+ relativeLocationAlongProfileDictionary = new Dictionary();
+ ID = -1;
+ }
+
+ ///
+ /// Gets or sets the ID.
+ ///
+ ///
+ /// The ID value should be unique.
+ ///
+ public int ID
+ {
+ get { return id; }
+ set
+ {
+ id = value;
+ }
+ }
+
+ ///
+ /// Gets the selected sensors.
+ ///
+ [XmlIgnore]
+ public IEnumerable Selection
+ {
+ get { return sensors; }
+ }
+
+ ///
+ /// Gets or sets the selection as list for UI (table) purposes.
+ ///
+ ///
+ /// The selection as list.
+ ///
+ [XmlIgnore]
+ public string SelectionAsString
+ {
+ get
+ {
+ string res = "";
+ foreach (var sensor in sensors)
+ {
+ res = res + sensor.ID + "; ";
+ }
+ return res;
+ }
+ set
+ {
+ ClearSelection();
+ var locSensors = ParseStringToSensorIDs(value);
+ if (pickSensors != null)
+ {
+ foreach (var sensorID in locSensors)
+ {
+ var sensor = PickSensors.Find(x => x.ID == sensorID);
+ if (sensor != null)
+ {
+ Add(sensor);
+ }
+ }
+ }
+ }
+ }
+
+ private List ParseStringToSensorIDs(string value)
+ {
+ value = value.Trim();
+ var ids = new List();
+ var idsarr = value.Split(new Char [] {';'}, StringSplitOptions.RemoveEmptyEntries);
+ foreach (var s in idsarr)
+ {
+ try
+ {
+ var val = Int32.Parse(s);
+ ids.Add(val);
+ }
+ catch (Exception)
+ {
+ // surpress errors, just do not use value
+ }
+ }
+ return ids;
+ }
+
+ ///
+ /// Persistable sensor array. Only for internal use
+ ///
+ public Sensor[] SensorArray
+ {
+ get { return sensors.ToArray(); }
+ set {
+ ClearSelection();
+ foreach (var sensor in value)
+ {
+ Add(sensor);
+ }
+ }
+ }
+
+ ///
+ /// Gets the sensor count.
+ ///
+ public int SensorCount
+ {
+ get { return sensors.Count; }
+ }
+
+ [XmlIgnore]
+ public IEnumerable> SensorRelativeLocations
+ {
+ get { return relativeLocationAlongProfileDictionary; }
+ }
+
+ [XmlIgnore]
+ public List PickSensors
+ {
+ get { return pickSensors; }
+ set { pickSensors = value; }
+ }
+
+ ///
+ /// Determines whether this instance is valid.
+ ///
+ ///
+// public bool IsValid()
+// {
+// IEnumerable validationResults = Validator.Validate(this);
+// return !validationResults.Any();
+// }
+
+ ///
+ /// Determines whether this instance is transient (associated with an invalid ID).
+ ///
+ ///
+ /// true if this instance is transient; otherwise, false.
+ ///
+ public bool IsTransient()
+ {
+ return ID <= 0;
+ }
+
+ ///
+ /// Sets the relative location.
+ ///
+ /// The sensor.
+ /// The value.
+ public void SetRelativeLocation(Sensor sensor, double value)
+ {
+ relativeLocationAlongProfileDictionary[sensor] = value;
+ }
+
+ ///
+ /// Adds the specified sensor to the selected sensor list for this group.
+ ///
+ /// The sensor to add.
+ public void Add(Sensor sensor)
+ {
+ sensors.Add(sensor);
+ if (!relativeLocationAlongProfileDictionary.ContainsKey(sensor))
+ relativeLocationAlongProfileDictionary.Add(sensor, 0);
+
+ }
+
+ ///
+ /// Removes the specified sensor from the selected sensor list from this group.
+ ///
+ /// The sensor to remove.
+ public void Remove(Sensor sensor)
+ {
+ sensors.Remove(sensor);
+ if (relativeLocationAlongProfileDictionary.ContainsKey(sensor))
+ relativeLocationAlongProfileDictionary.Remove(sensor);
+ }
+
+ ///
+ /// Clears the sensor selection
+ ///
+ public void ClearSelection()
+ {
+ sensors.Clear();
+ relativeLocationAlongProfileDictionary.Clear();
+ }
+
+ public override string ToString()
+ {
+ return ID.ToString();
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/RWSchematizationFactorsResult.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/RWSchematizationFactorsResult.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/RWSchematizationFactorsResult.cs (revision 334)
@@ -0,0 +1,116 @@
+// 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.Collections.Generic;
+using Deltares.DamEngine.Data.Standard.Calculation;
+
+namespace Deltares.DamEngine.Data.General.Results
+{
+ public class RWSchematizationFactorsResult
+ {
+ private List schematizationFactorResults = new List();
+
+ public List SchematizationFactorResults
+ {
+ get { return schematizationFactorResults; }
+ set { schematizationFactorResults = value; }
+ }
+ }
+
+ public class RWSchematizationFactorResult
+ {
+ private Location location;
+ private SchematizationType schematizationType;
+ private string soilProfileName;
+ private double schematizationFactor;
+ private double summedProfileProbability;
+ private CalculationResult calculationResult;
+ private ScenarioType decisiveScenarioName;
+ private string originalDecisiveSoilProfileName;
+ private double detrimentFactor;
+ private double safetyFactor;
+
+ public virtual Location Location
+ {
+ get { return location; }
+ set { location = value; }
+ }
+
+ public string LocationName
+ {
+ get { return this.Location != null ? this.Location.Name : ""; }
+ }
+
+ public SchematizationType SchematizationType
+ {
+ get { return schematizationType; }
+ set { schematizationType = value; }
+ }
+
+ public string SoilProfileName
+ {
+ get { return soilProfileName; }
+ set { soilProfileName = value; }
+ }
+
+ public string OriginalDecisiveSoilProfileName
+ {
+ get { return originalDecisiveSoilProfileName; }
+ set { originalDecisiveSoilProfileName = value; }
+ }
+
+ public double SchematizationFactor
+ {
+ get { return schematizationFactor; }
+ set { schematizationFactor = value; }
+ }
+
+ public double SummedProfileProbability
+ {
+ get { return summedProfileProbability; }
+ set { summedProfileProbability = value; }
+ }
+
+ public ScenarioType DecisiveScenarioName
+ {
+ get { return decisiveScenarioName; }
+ set { decisiveScenarioName = value; }
+ }
+
+ public double DetrimentFactor
+ {
+ get { return detrimentFactor; }
+ set { detrimentFactor = value; }
+ }
+
+ public double SafetyFactor
+ {
+ get { return safetyFactor; }
+ set { safetyFactor = value; }
+ }
+
+ public CalculationResult CalculationResult
+ {
+ get { return calculationResult; }
+ set { calculationResult = value; }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/Line.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/Line.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/Line.cs (revision 334)
@@ -0,0 +1,204 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Geometry Line, connecting begin point to end point with a straight line.
+ ///
+ public class Line
+ {
+ private readonly Line line = new Line();
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Line() : this(null, null) {}
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The begin point.
+ /// The end point.
+ public Line(Point2D beginPoint, Point2D endPoint)
+ {
+ BeginPoint = beginPoint;
+ EndPoint = endPoint;
+ }
+
+ ///
+ /// Gets or sets the begin point.
+ ///
+ ///
+ /// The begin point.
+ ///
+ public Point2D BeginPoint
+ {
+ get
+ {
+ return line.Start;
+ }
+ set
+ {
+ line.Start = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the end point.
+ ///
+ ///
+ /// The end point.
+ ///
+ public Point2D EndPoint
+ {
+ get
+ {
+ return line.End;
+ }
+ set
+ {
+ line.End = value;
+ }
+ }
+
+ ///
+ /// Creates the horizontal z line.
+ ///
+ /// The x1.
+ /// The x2.
+ /// The z.
+ public void CreateHorizontalZLine(double x1, double x2, double z)
+ {
+ SetBeginAndEndPoints(new Point2D{ X = x1, Z = z}, new Point2D{ X = x2, Z = z});
+ }
+
+ ///
+ /// Sets the begin and end points.
+ ///
+ /// The begin point.
+ /// The end point.
+ public void SetBeginAndEndPoints(Point2D beginPoint, Point2D endPoint)
+ {
+ BeginPoint = beginPoint;
+ EndPoint = endPoint;
+ }
+
+ ///
+ /// Calculate intersection with another projected to the XZ plane.
+ ///
+ /// The other line segment.
+ /// An intersection point in the XZ-plane, or null in case no intersection.
+ public Point2D GetIntersectPointXz(Line other)
+ {
+ Point2D intersectionPoint;
+ var isIntersecting = line.IntersectsZ(other.line, out intersectionPoint);
+
+ return isIntersecting ? intersectionPoint : null;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public class Line where T : Point2D, new()
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Line() : this(null, null) {}
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The start.
+ /// The end.
+ public Line(T start, T end)
+ {
+ Start = start;
+ End = end;
+ }
+
+ ///
+ /// Gets or sets the start.
+ ///
+ ///
+ /// The start.
+ ///
+ public T Start { get; set; }
+
+ ///
+ /// Gets or sets the end.
+ ///
+ ///
+ /// The end.
+ ///
+ public T End { get; set; }
+
+ ///
+ /// Intersectses the z.
+ ///
+ /// The line.
+ /// The intersection point.
+ ///
+ public bool IntersectsZ(Line line, out T intersectionPoint)
+ {
+ return Intersects(line, out intersectionPoint);
+ }
+
+ private bool Intersects(Line line, out T intersectionPoint)
+ {
+ intersectionPoint = null;
+
+ var dx1 = End.X - Start.X;
+ var dx2 = line.End.X - line.Start.X;
+
+ var dyz1 = End.Z - Start.Z;
+ var dyz2 = line.End.Z - line.Start.Z;
+ var yz = Start.Z;
+ var yzLine = line.Start.Z;
+
+ var noem = dx1*dyz2 - dyz1*dx2;
+ if (Math.Abs(noem) > 0.0)
+ {
+ var u = (dx2*(yz - yzLine) - dyz2*(Start.X - line.Start.X))/noem;
+ if ((u >= 0.0) && (u <= 1.0))
+ {
+ var v = (dx1*(yz - yzLine) - dyz1*(Start.X - line.Start.X))/noem;
+
+ if ((v >= 0.0) && (v <= 1.0))
+ {
+ intersectionPoint = new T
+ {
+ X = Start.X + u * dx1,
+ Z = yz + u * dyz1
+ };
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/TimeSeries/TimeStep.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/TimeSeries/TimeStep.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/TimeSeries/TimeStep.cs (revision 334)
@@ -0,0 +1,58 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General.TimeSeries
+{
+ public class TimeStep
+ {
+ public TimeStep()
+ {
+ DividerSpecified = false;
+ }
+
+ public TimeStepUnit Unit { get; set; }
+
+ private uint divider;
+ public uint Divider
+ {
+ get { return divider; }
+ set
+ {
+ divider = value;
+ DividerSpecified = true;
+ }
+ }
+
+ public bool DividerSpecified { get; set; }
+ public bool MultiplierSpecified { get; set; }
+
+ private uint multiplier;
+ public uint Multiplier
+ {
+ get { return multiplier; }
+ set
+ {
+ multiplier = value;
+ MultiplierSpecified = true;
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/TimeSeries/TimeSerie.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/TimeSeries/TimeSerie.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/TimeSeries/TimeSerie.cs (revision 334)
@@ -0,0 +1,239 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.General.TimeSeries
+{
+ public class TimeSerie
+ {
+ ///
+ /// List of parameter identifiers used in Fews timeseries
+ ///
+ public const string WaterLevelParameterId = "Waterlevel";
+ public const string WaterLevelMeanParameterId = "WaterlevelMean";
+ public const string WaterLevelStdParameterId = "WaterlevelStdev";
+ public const string WaterLevelDistParameterId = "WaterlevelDistribution";
+ public const string WaterPressureParameterId = "Waterpressure";
+ public const string PiezoMetricHeadId = "PiezoMetricHead";
+
+ private readonly TimeStep timeStep;
+ //Bka: read only not possible to serialize to DB private readonly List entries;
+ private IList entries;
+
+ public const double DefaultMissingValue = -999.0;
+
+ public TimeSerie()
+ {
+ timeStep = new TimeStep();
+ entries = new List();
+ ForecastDateTime = DateTime.MinValue;
+ }
+
+ public string Type { get; set; }
+ public string LocationId { get; set; }
+ public string ParameterId { get; set; }
+ public TimeStep TimeStep { get { return timeStep; } }
+ public DateTime StartDateTime { get; set; }
+ public DateTime EndDateTime { get; set; }
+ public DateTime ForecastDateTime { get; set; }
+ public double MissVal { get; set; }
+ public string LongName { get; set; }
+ public string StationName { get; set; }
+ public string Units { get; set; }
+ public string SourceOrganisation { get; set; }
+ public string SourceSystem { get; set; }
+ public string FileDescription { get; set; }
+ public DateTime? CreationDateTime { get; set; }
+ public string Region { get; set; }
+
+ public virtual IList Entries
+ {
+ get { return entries; }
+ set { entries = value; }
+ }
+
+ public string Comment { get; set; }
+
+ ///
+ /// Creates a shallow copy of the current time serie and applies the map function to each of its entries
+ ///
+ /// The time serie entry function which maps uses the current value as input
+ /// Time serie (clone) with new calculated entries
+ public TimeSerie Map(Func function)
+ {
+ return Map(ParameterId, function);
+ }
+
+ ///
+ /// Creates a shallow copy of the current time serie and applies the map function to each of its entries
+ ///
+ /// The (new) id of the parameter in the cloned time serie
+ /// The (new) location id of the cloned time serie
+ /// The time serie entry function which maps uses the current value as input
+ /// Time serie (clone) with new calculated entries
+ public TimeSerie Map(string parameterId, string locationId, Func function)
+ {
+ return Map(this, parameterId, locationId, function);
+ }
+
+ ///
+ /// Creates a shallow copy of the current time serie and applies the map function to each of its entries
+ ///
+ /// The (new) id of the parameter in the cloned time serie
+ /// The time serie entry function which maps uses the current value as input
+ /// Time serie (clone) with new calculated entries
+ public TimeSerie Map(string parameterId, Func function)
+ {
+ return Map(this, parameterId, function);
+ }
+
+ ///
+ /// Creates a shallow copy of the current time serie and applies the map function to each of its entries
+ ///
+ /// The time serie to map from
+ /// The (new) id of the parameter in the cloned time serie
+ /// The time serie entry function which maps uses the current value as input
+ /// Time serie (clone) with new calculated entries
+ public static TimeSerie Map(TimeSerie timeSerie, string parameterId, Func function)
+ {
+ return Map(timeSerie, parameterId, null, function);
+ }
+
+ ///
+ /// Creates a shallow copy of the current time serie and applies the map function to each of its entries
+ ///
+ /// The time serie to map from
+ /// The (new) id of the parameter in the cloned time serie
+ /// The (new) location id of the cloned time serie
+ /// The time serie entry function which maps uses the current value as input
+ /// Time serie (clone) with new calculated entries
+ public static TimeSerie Map(TimeSerie timeSerie, string parameterId, string locationId, Func function)
+ {
+ var result = CreateTimeSerie(timeSerie, parameterId);
+ if (!(string.IsNullOrEmpty(locationId) || locationId.Trim() == ""))
+ result.LocationId = locationId;
+
+ foreach (var entry in timeSerie.Entries)
+ result.Entries.Add(function(entry));
+ return result;
+ }
+
+ ///
+ /// Gets a shallow copy of the time serie without the time serie entries
+ ///
+ /// A copy of this time serie
+ public TimeSerie GetShallowCopy()
+ {
+ var serie = new TimeSerie
+ {
+ Type = Type,
+ ParameterId = ParameterId,
+ LocationId = LocationId,
+ StartDateTime = StartDateTime,
+ EndDateTime = EndDateTime,
+ ForecastDateTime = ForecastDateTime,
+ MissVal = MissVal,
+ LongName = LongName,
+ StationName = StationName,
+ SourceOrganisation = SourceOrganisation,
+ SourceSystem = SourceSystem,
+ FileDescription = FileDescription,
+ CreationDateTime = CreationDateTime,
+ Region = Region,
+ Units = Units,
+ TimeStep =
+ {
+ Multiplier = TimeStep.Multiplier,
+ Divider = TimeStep.Divider,
+ Unit = TimeStep.Unit
+ }
+ };
+
+ serie.Entries.Clear();
+ return serie;
+ }
+
+ public static TimeSerie CreateTimeSerie(string locationId)
+ {
+ var timeSerie = new TimeSerie
+ {
+ MissVal = DefaultMissingValue,
+ ParameterId = WaterLevelParameterId,
+ LocationId = locationId,
+ StationName = locationId,
+ Type = "instantaneous",
+ Units = "m",
+ Comment = ""
+ };
+
+ return timeSerie;
+ }
+
+
+ ///
+ /// Creates a time serie by copying data from the source time serie without
+ /// time serie entries (shallow copy)
+ ///
+ /// The source time serie used to copy from
+ /// The new parameter ID
+ /// A time serie copy without time entries
+ public static TimeSerie CreateTimeSerie(TimeSerie source, string parameterId)
+ {
+ var serie = source.GetShallowCopy();
+ serie.ParameterId = parameterId;
+ serie.Units = "-";
+ serie.Comment = "";
+ return serie;
+ }
+
+ public double GetValue(DateTime dateTime)
+ {
+ foreach (TimeSerieEntry entry in Entries)
+ {
+ if (entry.DateTime >= dateTime)
+ {
+ return entry.Value;
+ }
+ }
+
+ return -1;
+ }
+
+ public string GetNearestBasisFileName(DateTime dateTime)
+ {
+ string res = "";
+ double mindiff = 1e99;
+ double diff;
+ foreach (TimeSerieEntry entry in Entries)
+ {
+ diff = Math.Abs(entry.DateTime.ToFileTimeUtc() - dateTime.ToFileTimeUtc());
+ if (diff < mindiff)
+ {
+ res = entry.BasisFileName;
+ mindiff = diff;
+ }
+ }
+ return res;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (revision 334)
@@ -0,0 +1,496 @@
+// 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 System.Xml.Serialization;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Standard;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ ///
+ /// A SoilSurfaceProfile constructs a SoilProfile2D object by merging an existing SoilProfile1D with a SurfaceLine
+ ///
+ /// Note that actual contruction of 2D based on surface line and 1D happens on setting the properties using dirty flags.
+ ///
+ public class SoilSurfaceProfile : SoilProfile2D
+ {
+ private Soil dikeEmbankmentMaterial;
+ private bool dirty;
+ private bool initial = true;
+ private SoilProfile1D soilProfile;
+ private SoilProfile1D orgSoilProfile;
+ private GeometryPointString surfaceLine;
+ private SurfaceLine2 surfaceLine2;
+ private bool createSettlementZones;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SoilSurfaceProfile()
+ {
+ Name = "Soil Surface Profile";
+ }
+
+ ///
+ /// Gets or sets the surface line.
+ ///
+ ///
+ /// The surface line.
+ ///
+ [Validate]
+ public GeometryPointString SurfaceLine
+ {
+ get
+ {
+ return surfaceLine;
+ }
+ set
+ {
+ surfaceLine = value;
+ dirty = true;
+ }
+ }
+
+ ///
+ /// Gets or sets the surface line2.
+ ///
+ [Validate]
+ public SurfaceLine2 SurfaceLine2
+ {
+ get
+ {
+ return surfaceLine2;
+ }
+ set
+ {
+ surfaceLine2 = value;
+ if (surfaceLine2 != null)
+ {
+ SurfaceLine = surfaceLine2.Geometry;
+ }
+ else
+ {
+ SurfaceLine = null;
+ }
+ dirty = true;
+ }
+ }
+
+ ///
+ /// Gets or sets the soil profile.
+ ///
+ ///
+ /// The soil profile.
+ ///
+ [Validate]
+ public SoilProfile1D SoilProfile
+ {
+ get
+ {
+ return orgSoilProfile;
+ }
+ set
+ {
+ orgSoilProfile = value;
+ dirty = true;
+ }
+ }
+
+ ///
+ /// Gets or sets the dike material.
+ ///
+ ///
+ /// The dike material.
+ ///
+ public Soil DikeEmbankmentMaterial
+ {
+ get
+ {
+ return dikeEmbankmentMaterial;
+ }
+ set
+ {
+ dikeEmbankmentMaterial = value;
+ dirty = true;
+ }
+ }
+
+ ///
+ /// List of preconsolidation stresses
+ ///
+ [XmlIgnore]
+ public override List PreconsolidationStresses
+ {
+ get
+ {
+ if (orgSoilProfile != null)
+ {
+ return orgSoilProfile.PreconsolidationStresses;
+ }
+ return null;
+ }
+ }
+
+ ///
+ /// Gets the surfaces.
+ ///
+ ///
+ /// The surfaces.
+ ///
+ [XmlIgnore]
+ [Validate]
+ public override IList Surfaces
+ {
+ get
+ {
+ if (initial || dirty)
+ {
+ UpdateLayers();
+ }
+ return base.Surfaces;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether to [create settlement zones].
+ ///
+ ///
+ /// true if [create settlement zones]; otherwise, false.
+ ///
+ public bool CreateSettlementZones
+ {
+ get
+ {
+ return createSettlementZones;
+ }
+ set
+ {
+ createSettlementZones = value;
+ }
+ }
+
+ ///
+ /// Generates a 1D profile at a given x
+ ///
+ ///
+ /// Generated 1D soil profile
+ public override SoilProfile1D GetSoilProfile1D(double x)
+ {
+ if (initial || dirty)
+ {
+ initial = false;
+
+ UpdateLayers();
+ }
+
+ // Try to obtain a cached soil profile (performance optimization)
+ var soilProfile1D = GetCachedSoilProfile1D(x);
+ if (soilProfile1D != null)
+ {
+ return soilProfile1D;
+ }
+
+ // Otherwise, create and configure a new soil profile
+ soilProfile1D = new SoilProfile1D();
+
+ double top = SurfaceLine.GetZatX(x);
+ soilProfile1D.BottomLevel = soilProfile.BottomLevel;
+
+ if (top > soilProfile.TopLevel)
+ {
+ var emptyTopLayer = new SoilLayer1D(null, top)
+ {
+ SoilProfile = soilProfile1D
+ };
+ soilProfile1D.Layers.Add(emptyTopLayer);
+ }
+
+ for (int i = 0; i < soilProfile.Layers.Count; i++)
+ {
+ SoilLayer1D layer = soilProfile.Layers[i];
+ if (layer.BottomLevel < top)
+ {
+ // Perform without publishing events because otherwise the soil profile cache would get lost
+ var newLayer = new SoilLayer1D(layer.Soil, Math.Min(layer.TopLevel, top))
+ {
+ IsAquifer = layer.IsAquifer,
+ WaterpressureInterpolationModel = layer.WaterpressureInterpolationModel,
+ SoilProfile = soilProfile1D
+ };
+ soilProfile1D.Layers.Add(newLayer);
+ }
+ }
+
+ // Add the newly created soil profile to the cache
+ cachedSoilProfiles1D[x] = soilProfile1D;
+
+ return soilProfile1D;
+ }
+
+ ///
+ /// Returns a that represents this instance (either Name or SoilProfile).
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ if (!string.IsNullOrEmpty(Name))
+ {
+ return Name;
+ }
+ if (orgSoilProfile != null)
+ {
+ return orgSoilProfile.ToString();
+ }
+ return "Soil Surface Profile with null Soil Profile";
+ }
+
+ ///
+ /// Converts to soil profile2D.
+ ///
+ ///
+ public SoilProfile2D ConvertToSoilProfile2D()
+ {
+ var soilProfile2D = new SoilProfile2D
+ {
+ Geometry = Geometry
+ };
+ soilProfile2D.Surfaces.AddRange(Surfaces);
+ soilProfile2D.Name = Name;
+ return soilProfile2D;
+
+ }
+
+ ///
+ /// Updates the dike material.
+ ///
+ private void UpdateDikeMaterial()
+ {
+ if (soilProfile != null && SurfaceLine != null)
+ {
+ double topSurfaceLine = SurfaceLine.GetMaxZ();
+ if (!double.IsNaN(topSurfaceLine) && (soilProfile.Layers.Count == 0 || soilProfile.TopLevel < topSurfaceLine))
+ {
+ double newTopLevel = topSurfaceLine + 0.5;
+
+ if (soilProfile.Layers.Count > 0 && soilProfile.Layers[0].Soil == DikeEmbankmentMaterial)
+ {
+ SoilLayer1D dikeMaterialLayer = soilProfile.Layers[0];
+ dikeMaterialLayer.TopLevel = newTopLevel;
+ }
+ else
+ {
+ // Add toplayer of dikematerial
+ var newLayer = new SoilLayer1D
+ {
+ TopLevel = newTopLevel,
+ Soil = DikeEmbankmentMaterial,
+ };
+
+ // special handling for dummy soil profiles
+ if (soilProfile.Layers.Count == 0 && DikeEmbankmentMaterial == null)
+ {
+ soilProfile.BottomLevel = SurfaceLine.GetMinZ() - 1;
+ }
+
+ soilProfile.Layers.Insert(0, newLayer);
+ soilProfile.EnsureLastLayerHasHeight();
+ }
+ }
+ }
+ }
+
+ ///
+ /// Adds the layer geometry.
+ ///
+ /// The data.
+ /// The layer.
+ /// The minimum x.
+ /// The maximum x.
+ private static void AddLayerGeometry(GeometryData data, SoilLayer1D layer, double minX, double maxX)
+ {
+ var top = layer.TopLevel;
+ var bottom = layer.BottomLevel;
+
+ if (Math.Abs(layer.BottomLevel - layer.SoilProfile.BottomLevel) < GeometryConstants.Accuracy)
+ {
+ bottom = data.Bottom;
+ }
+
+ var bottomLeft = new Point2D(minX, bottom);
+ var bottomRight = new Point2D(maxX,bottom);
+ var topLeft = new Point2D(minX, top);
+ var topRight = new Point2D(maxX, top);
+
+ data.Points.Add(bottomLeft);
+ data.Points.Add(bottomRight);
+ data.Points.Add(topLeft);
+ data.Points.Add(topRight);
+
+ data.Curves.Add(new GeometryCurve(bottomLeft, bottomRight));
+ data.Curves.Add(new GeometryCurve(bottomRight, topRight));
+ data.Curves.Add(new GeometryCurve(topRight, topLeft));
+ data.Curves.Add(new GeometryCurve(topLeft, bottomLeft));
+ }
+
+ private void AddSurfaceLineGeometry(GeometryData data)
+ {
+ var current = new Point2D(surfaceLine.Points[0].X, surfaceLine.Points[0].Z);
+ data.Points.Add(current);
+ for (int i = 1; i < surfaceLine.Points.Count; ++i)
+ {
+ var previous = current;
+ current = new Point2D(surfaceLine.Points[i].X, surfaceLine.Points[i].Z);
+
+ data.Points.Add(current);
+ data.Curves.Add(new GeometryCurve(previous, current));
+ }
+ }
+
+ private void AddSettlementZones(GeometryData locGeometry)
+ {
+
+ if (surfaceLine2 != null && surfaceLine2.HasDike())
+ {
+ var xToeRiver = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X;
+ AddVerticalAt(locGeometry, xToeRiver);
+ var xTopRiver = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X;
+ var xRiver = xToeRiver + (xTopRiver - xToeRiver) / 3.0;
+ AddVerticalAt(locGeometry, xRiver);
+
+ var xToePolder = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X;
+ var xTopPolder = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X;
+ var xPolder = xTopPolder + 2 * (xToePolder - xTopPolder) / 3.0;
+ AddVerticalAt(locGeometry, xPolder);
+ AddVerticalAt(locGeometry, xToePolder);
+ }
+ }
+
+ private void AddVerticalAt(GeometryData aGeometry, double x)
+ {
+ const double zMax = 100000.0;
+ var topX = new Point2D(x, zMax);
+ var bottomX = new Point2D(x, -zMax);
+ aGeometry.Points.Add(topX);
+ aGeometry.Points.Add(bottomX);
+ aGeometry.Curves.Add(new GeometryCurve(topX, bottomX));
+ //aGeometry.NewlyEffectedCurves.Add(aGeometry.Curves.Last());##Bka
+ }
+
+ private void BuildGeometryModel()
+ {
+ if (surfaceLine == null
+ || soilProfile == null
+ || soilProfile.Layers.Count == 0
+ || surfaceLine.GetMaxZ() < soilProfile.BottomLevel
+ || surfaceLine.Points.Count < 2)
+ {
+ return;
+ }
+
+ var bounds = SurfaceLine.GetGeometryBounds();
+ double minX = bounds.Left;
+ double maxX = bounds.Right;
+
+ Geometry.Clear();
+ Geometry.Left = minX;
+ Geometry.Right = maxX;
+ Geometry.Bottom = Math.Min(soilProfile.BottomLevel, surfaceLine.GetMinZ() - 1);
+
+ // add profile geometry
+ soilProfile.Layers.Sort();
+ foreach (var layer in soilProfile.Layers)
+ {
+ AddLayerGeometry(Geometry, layer, minX, maxX);
+ }
+
+ // add surface line geometry
+ AddSurfaceLineGeometry(Geometry);
+
+ // add the extra lines to create the settlementzones if required
+ if (createSettlementZones)
+ {
+ AddSettlementZones(Geometry);
+ }
+// 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
+// });
+// }
+// } ##Bka
+ }
+
+ ///
+ /// Updates the layers.
+ ///
+ private void UpdateLayers()
+ {
+// 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/trunk/src/Deltares.DamEngine.Data/General/NWO/NonWaterRetainingObject.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/NWO/NonWaterRetainingObject.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/NWO/NonWaterRetainingObject.cs (revision 334)
@@ -0,0 +1,158 @@
+// 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.Geometry;
+
+namespace Deltares.DamEngine.Data.General.NWO
+{
+
+ public class NonWaterRetainingObjectException : ApplicationException
+ {
+ public NonWaterRetainingObjectException(string message)
+ : base(message)
+ {
+ }
+ }
+
+ public class NonWaterRetainingObject
+ {
+ public virtual string NwoId { get; set; }
+ public virtual NonWaterRetainingObjectCategory Category { get; set; }
+ public virtual NonWaterRetainingObjectType Type { get; set; }
+ public virtual PhreaticAdaptionType PhreaticAdaption { get; set; }
+ public virtual double H1 { get; set; }
+ public virtual double H2 { get; set; }
+ public virtual double N1 { get; set; }
+ public virtual double N2 { get; set; }
+ public virtual double B { get; set; }
+ public virtual double StepSizeX { get; set; }
+ public virtual double MaxDistanceFromToe { get; set; }
+
+ public double Btotal ()
+ {
+ double bTotal = (H1 * N1) + (Math.Sqrt((B*B - (Math.Pow(H2-H1, 2))))) + (H2 * N2);
+ return bTotal;
+ }
+
+ public GeometryPoint Point1 { get; set; }
+ public GeometryPoint Point2 { get; set; }
+ public GeometryPoint Point3 { get; set; }
+ public GeometryPoint Point4 { get; set; }
+
+ ///
+ ///
+ ///
+ ///
+ public void GetDefaultValuesPerTreeType(NonWaterRetainingObjectType type)
+ {
+
+ switch (type)
+ {
+ case NonWaterRetainingObjectType.Oak:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ case NonWaterRetainingObjectType.Alder:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ case NonWaterRetainingObjectType.Poplar:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ default:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void GetDefaultValuesPerMainType(NonWaterRetainingObjectType type)
+ {
+
+ switch (type)
+ {
+ case NonWaterRetainingObjectType.GasMain:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ case NonWaterRetainingObjectType.WaterMain:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ default:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void GetDefaultValuesPerCategoryAndType(NonWaterRetainingObjectCategory category, NonWaterRetainingObjectType type)
+ {
+ switch (category)
+ {
+ case NonWaterRetainingObjectCategory.Tree: GetDefaultValuesPerTreeType(type);
+ break;
+ case NonWaterRetainingObjectCategory.Main: GetDefaultValuesPerMainType(type);
+ break;
+ }
+ }
+
+ public void Validate()
+ {
+ if (Btotal() <= 0)
+ throw new NonWaterRetainingObjectException("NonWaterReatiningObject is invalid. Its total width is smaller than or equal to 0.");
+ if (MaxDistanceFromToe <= Btotal())
+ throw new NonWaterRetainingObjectException("NonWaterReatiningObject is invalid. The required maximum distance from toe is smaller than or equal to the total width.");
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/RWScenariosResult.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/RWScenariosResult.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/RWScenariosResult.cs (revision 334)
@@ -0,0 +1,278 @@
+// 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.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using Deltares.DamEngine.Data.General;
+
+namespace Deltares.DamEngine.Data.RWScenarios
+{
+ public class RWScenariosResult : RWResult
+ {
+ private IList rwScenarioResults = new List();
+
+ public RWScenariosResult()
+ {
+ }
+
+ public IList RWScenarioResults
+ {
+ get { return rwScenarioResults; }
+ private set { rwScenarioResults = value; }
+ }
+
+ public RWScenarioResult GetScenarioResult(ScenarioType scenarioType)
+ {
+ foreach (RWScenarioResult scenarioResult in this.RWScenarioResults)
+ {
+ if (scenarioResult.ScenarioType == scenarioType)
+ {
+ return scenarioResult;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ public class RWScenarioResult : RWResult
+ {
+ private LoadSituation loadSituation = LoadSituation.Wet;
+ private DikeDrySensitivity _dikeDrySensitivity = DikeDrySensitivity.None;
+ private HydraulicShortcutType hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
+ private UpliftType upliftType = UpliftType.NoUplift;
+ private MStabModelType modelOption;
+
+ private ScenarioType scenarioType = ScenarioType.Scenario01;
+
+ private IList rwScenarioProfileResults = new List();
+
+ public RWScenarioResult()
+ {
+ }
+
+ public IList RWScenarioProfileResults
+ {
+ get { return rwScenarioProfileResults; }
+ private set { rwScenarioProfileResults = value; }
+ }
+
+ public LoadSituation LoadSituation
+ {
+ get { return loadSituation; }
+ set { loadSituation = value; }
+ }
+
+ public DikeDrySensitivity DikeDrySensitivity
+ {
+ get { return _dikeDrySensitivity; }
+ set { _dikeDrySensitivity = value; }
+ }
+
+ public HydraulicShortcutType HydraulicShortcutType
+ {
+ get { return hydraulicShortcutType; }
+ set { hydraulicShortcutType = value; }
+ }
+
+ public UpliftType UpliftType
+ {
+ get { return upliftType; }
+ set { upliftType = value; }
+ }
+
+ public MStabModelType ModelOption
+ {
+ get { return modelOption; }
+ set { modelOption = value; }
+ }
+
+ public ScenarioType ScenarioType
+ {
+ get { return scenarioType; }
+ set { scenarioType = value; }
+ }
+ }
+
+ public class RWScenarioProfileResult : RWResult
+ {
+ private FailureMechanismSystemType failureMechanismType = FailureMechanismSystemType.StabilityInside;
+ private DikeDrySensitivity _dikeDrySensitivity = DikeDrySensitivity.None;
+ private HydraulicShortcutType hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
+ private UpliftType upliftType = UpliftType.NoUplift;
+ private LoadSituation loadSituation = LoadSituation.Wet;
+ private MStabModelType mstabModelOption;
+ private PipingModelType pipingModelOption;
+
+ private SoilGeometryProbability soilGeometryProbability = null;
+ private Location location = null;
+
+ private ScenarioType scenarioType = ScenarioType.Scenario01;
+ private string baseFileName = "";
+
+ public const string CalculationCategory = "Calculation";
+
+ public RWScenarioProfileResult()
+ {
+ }
+
+ public virtual Location Location
+ {
+ get { return location; }
+ set { location = value; }
+ }
+
+ public string LocationName
+ {
+ get { return this.Location.Name; }
+ }
+
+ public double DetrimentFactor
+ {
+ get
+ {
+ // For Piping, ignore the given detriment factor and use the required safety for Piping
+ if (scenarioType == ScenarioType.Scenario10 || scenarioType == ScenarioType.Scenario11)
+ return DamGlobalConstants.RequiredSafetyPipingForAssessment;
+ return this.Location.DetrimentFactor;
+ }
+ }
+
+ public string SoilProfileName
+ {
+ get
+ {
+ var res = "";
+ if (SoilGeometryProbability != null)
+ res = SoilGeometryProbability.SoilProfile.Name;
+ return res;
+ }
+ }
+
+ public double SoilProfileProbability
+ {
+ get
+ {
+ var res = 0.0;
+ if (SoilGeometryProbability != null)
+ res = SoilGeometryProbability.Probability;
+ return res;
+ }
+ }
+
+ public LoadSituation LoadSituation
+ {
+ get { return loadSituation; }
+ set { loadSituation = value; }
+ }
+
+ public DikeDrySensitivity DikeDrySensitivity
+ {
+ get { return _dikeDrySensitivity; }
+ set { _dikeDrySensitivity = value; }
+ }
+
+ public HydraulicShortcutType HydraulicShortcutType
+ {
+ get { return hydraulicShortcutType; }
+ set { hydraulicShortcutType = value; }
+ }
+
+ public UpliftType UpliftType
+ {
+ get { return upliftType; }
+ set { upliftType = value; }
+ }
+
+ public MStabModelType MstabModelOption
+ {
+ get { return mstabModelOption; }
+ set { mstabModelOption = value; }
+ }
+
+ public PipingModelType PipingModelOption
+ {
+ get { return pipingModelOption; }
+ set { pipingModelOption = value; }
+ }
+
+ public MStabParameters MStabParameters { get; set; }
+
+ public ScenarioType ScenarioType
+ {
+ get { return scenarioType; }
+ set { scenarioType = value; }
+ }
+
+ public string BaseFileName
+ {
+ get { return baseFileName; }
+ set { baseFileName = value; }
+ }
+
+ public string InputFile
+ {
+ get { return DamProjectData.ProjectWorkingPath + Path.DirectorySeparatorChar + baseFileName + ".sti"; }
+ }
+
+ public string ResultFile
+ {
+ get
+ {
+ const string wmfExtension = ".wmf";
+ string fullBaseFilename = DamProjectData.ProjectWorkingPath + Path.DirectorySeparatorChar + baseFileName;
+ string fullFilename = fullBaseFilename + wmfExtension;
+ if (!File.Exists(fullFilename))
+ {
+ fullFilename = fullBaseFilename + "z1" + wmfExtension;
+ }
+ if (!File.Exists(fullFilename))
+ {
+ fullFilename = fullBaseFilename + "z2" + wmfExtension;
+ }
+ return fullFilename;
+ }
+ }
+
+ 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; } ##Bka: most probably unwanted, replace with other mechanism. Or delete when NOT USED
+ }
+
+ public FailureMechanismSystemType FailureMechanismType
+ {
+ get { return failureMechanismType; }
+ set { failureMechanismType = value; }
+ }
+
+ public SoilGeometryProbability SoilGeometryProbability
+ {
+ get { return soilGeometryProbability; }
+ set { soilGeometryProbability = value; }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/RWResult.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/RWResult.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/RWResult.cs (revision 334)
@@ -0,0 +1,86 @@
+// 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.ComponentModel;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.Standard.Calculation;
+
+namespace Deltares.DamEngine.Data.RWScenarios
+{
+ public class RWResult
+ {
+ private RWResultType _rwResultType = RWResultType.ProbabilityOfFailure;
+ private double safetyFactor = -1;
+ private double probabilityOfFailure = -1;
+ private CalculationResult calculationResult = CalculationResult.NoRun;
+ private ResultEvaluation resultEvaluation = ResultEvaluation.NotEvaluated;
+ private string notes = "";
+
+ public const string ResultCategory = "Results";
+
+ public RWResult()
+ {
+ }
+
+ public virtual RWResultType RwResultType
+ {
+ get { return _rwResultType; }
+ set { _rwResultType = value; }
+ }
+
+ public virtual double SafetyFactor
+ {
+ get { return safetyFactor; }
+ set { safetyFactor = value; }
+ }
+
+ public virtual double ProbabilityOfFailure
+ {
+ get { return probabilityOfFailure; }
+ set { probabilityOfFailure = value; }
+ }
+
+ public virtual CalculationResult CalculationResult
+ {
+ get { return calculationResult; }
+ set { calculationResult = value; }
+ }
+
+ public ResultEvaluation ResultEvaluation
+ {
+ get { return resultEvaluation; }
+ set
+ {
+ resultEvaluation = value;
+ }
+ }
+
+ [Description("Use this area to explain the valuation and for any further remarks")]
+ public string Notes
+ {
+ get { return notes; }
+ set
+ {
+ notes = value;
+ }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile.cs (revision 334)
@@ -0,0 +1,77 @@
+// 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.Collections.Generic;
+using Deltares.DamEngine.Data.Standard;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Soil Profile Object holding name, location and other common properties, base class for SoilProfile1D and SoilProfile2D
+ ///
+ public class SoilProfile : IName
+ {
+ private string name = "Soil Profile";
+ private readonly List preconsolidationStresses = new List();
+
+ ///
+ /// The name of the profile
+ ///
+ public virtual string Name
+ {
+ get
+ {
+ return name;
+ }
+ set
+ {
+ name = value;
+ }
+ }
+
+ ///
+ /// List of Preconsolidation stresses related to a soil profile
+ ///
+ [Validate]
+ public virtual List PreconsolidationStresses
+ {
+ get
+ {
+ return preconsolidationStresses;
+ }
+ }
+
+ ///
+ /// Assigns the specified soil profile.
+ ///
+ /// The soil profile.
+ public void Assign(SoilProfile soilProfile)
+ {
+ Name = soilProfile.Name;
+ foreach (var preconsolidationStress in soilProfile.PreconsolidationStresses)
+ {
+ var newPs = (PreConsolidationStress)preconsolidationStress.Clone();
+ preconsolidationStresses.Add(newPs);
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/JobResultInterpreter.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/JobResultInterpreter.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/JobResultInterpreter.cs (revision 334)
@@ -0,0 +1,60 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General.Results
+{
+ public class JobResultInterpreter
+ {
+ public static JobResult GetJobResult(double result, double demand, bool smaller)
+ {
+ if (result >= DamGlobalConstants.NoRunValue)
+ {
+ return JobResult.NoRun;
+ }
+ else if (result < 0 || double.IsNaN(result))
+ {
+ return JobResult.Failed;
+ }
+ else if (smaller)
+ {
+ if (result < demand)
+ {
+ return JobResult.Bad;
+ }
+ else
+ {
+ return JobResult.Good;
+ }
+ }
+ else
+ {
+ if (result > demand)
+ {
+ return JobResult.Bad;
+ }
+ else
+ {
+ return JobResult.Good;
+ }
+ }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/TimeSeries/TimeSerieEntry.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/TimeSeries/TimeSerieEntry.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/TimeSeries/TimeSerieEntry.cs (revision 334)
@@ -0,0 +1,85 @@
+// 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.Standard;
+
+namespace Deltares.DamEngine.Data.General.TimeSeries
+{
+ public class TimeSerieEntry
+ {
+ public TimeSerieEntry()
+ {
+ }
+
+ public TimeSerieEntry(DateTime dateTime, double value)
+ {
+ this.DateTime = dateTime;
+ this.Value = value;
+ }
+
+ public virtual DateTime DateTime { get; set; }
+ public virtual double Value { get; set; }
+ public virtual string BasisFileName { get; set; }
+ public string RelativeCalculationPathName { get; set; }
+
+ //public Stochast StochastValue { get; set; } #Bka: for now just disable.
+ public int Flag { get; set; }
+
+ public TimeSerieEntry GetShallowCopy()
+ {
+ return new TimeSerieEntry
+ {
+ DateTime = DateTime,
+ Flag = Flag,
+ };
+ }
+
+ public TimeSerieEntry Map(Func function)
+ {
+ return Map(0, function);
+ }
+
+ public TimeSerieEntry Map(double missingValue, Func function)
+ {
+ var entry = this.GetShallowCopy();
+ try
+ {
+ entry.Value = !this.Value.AlmostEquals(missingValue) ? function(this) : missingValue;
+ }
+ catch
+ {
+ entry.Value = missingValue;
+ }
+ return entry;
+ }
+
+ public void Assign(TimeSerieEntry entry)
+ {
+ this.DateTime = entry.DateTime;
+ this.Value = entry.Value;
+ this.BasisFileName = entry.BasisFileName;
+ //this.StochastValue = entry.StochastValue; #Bka: for now just disable
+ this.Flag = entry.Flag;
+ }
+
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/Gauges/GaugePLLine.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Gauges/GaugePLLine.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Gauges/GaugePLLine.cs (revision 334)
@@ -0,0 +1,74 @@
+// 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.Geometry;
+
+namespace Deltares.DamEngine.Data.General.Gauges
+{
+ public class GaugePLLinePoint : GeometryPoint
+ {
+ public GaugePLLinePoint() : this(null, null, null, null) { }
+
+ public GaugePLLinePoint(double? localX, double? localZ, string gaugeX, string gaugeZ)
+ {
+ this.X = localX;
+ this.Z = localZ;
+ this.GaugeIDX = gaugeX;
+ this.GaugeIDZ = gaugeZ;
+ }
+
+ public new double? X { get; set; }
+ public new double? Z { get; set; }
+ public string GaugeIDX { get; set; }
+ public string GaugeIDZ { get; set; }
+
+ public override string ToString()
+ {
+ return String.Format("({0}, {1}, '{2}', '{3}')", this.X.HasValue ? this.X.ToString() : "?", this.Z.HasValue ? this.Z.ToString() : "?", this.GaugeIDX, this.GaugeIDZ);
+ }
+ }
+
+ public class GaugePLLine : PolyLine
+ {
+ private GaugePLLine()
+ : base()
+ {
+ }
+
+ public GaugePLLine(PLLineType plLineType)
+ : this()
+ {
+ this.PLLineType = plLineType;
+ }
+
+ public PLLineType PLLineType { get; set; }
+
+ public override string ToString()
+ {
+ string result = String.Format("{0} | ", this.PLLineType.ToString());
+ foreach (GaugePLLinePoint point in this.Points)
+ result += point.ToString() + ", ";
+
+ return result;
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/General/IContext.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/General/IContext.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/General/IContext.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Data/General/DamJob.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/DamJob.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/DamJob.cs (revision 334)
@@ -0,0 +1,60 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class DamJob
+ {
+ private bool? run = false;
+ private object subject = null;
+ private string name;
+
+ public DamJob()
+ {
+ }
+
+ public DamJob(object subject) : this()
+ {
+ this.subject = subject;
+ }
+
+ public virtual string Name
+ {
+ get { return this.subject != null ? this.subject.ToString() : ""; }
+ set { name = value; }
+ }
+
+ public virtual bool? Run
+ {
+ get { return run; }
+ set
+ {
+ run = value;
+ }
+ }
+
+ public virtual object Subject
+ {
+ get { return subject; }
+ set { subject = value; }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryBounds.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryBounds.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryBounds.cs (revision 334)
@@ -0,0 +1,119 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Class holding the boundaries of a geometry object
+ ///
+ public class GeometryBounds
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GeometryBounds() : this(0, 0, 0, 0) { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The left.
+ /// The right.
+ /// The bottom.
+ /// The top.
+ public GeometryBounds(double left, double right, double bottom, double top)
+ {
+ Left = left;
+ Right = right;
+ Bottom = bottom;
+ Top = top;
+ }
+
+ ///
+ /// Gets or sets the left.
+ ///
+ ///
+ /// The left.
+ ///
+ public double Left { get; set; }
+
+ ///
+ /// Gets or sets the top.
+ ///
+ ///
+ /// The top.
+ ///
+ public double Top { get; set; }
+
+ ///
+ /// Gets or sets the right.
+ ///
+ ///
+ /// The right.
+ ///
+ public double Right { get; set; }
+
+ ///
+ /// Gets or sets the bottom.
+ ///
+ ///
+ /// The bottom.
+ ///
+ public double Bottom { get; set; }
+
+ ///
+ /// Determines whether the boundary contains the specified point.
+ ///
+ /// The x.
+ /// The y.
+ ///
+ public bool ContainsPoint(double x, double y)
+ {
+ return x >= Left && x <= Right && y >= Bottom && y <= Top;
+ }
+
+ ///
+ /// Implements the operator +.
+ ///
+ /// The bounds1.
+ /// The bounds2.
+ ///
+ /// The result of the operator.
+ ///
+ public static GeometryBounds operator +(GeometryBounds bounds1, GeometryBounds bounds2)
+ {
+ if (bounds2 == null)
+ {
+ return bounds1;
+ }
+ if (bounds1 == null)
+ {
+ return bounds2;
+ }
+
+ return new GeometryBounds(Math.Min(bounds1.Left, bounds2.Left),
+ Math.Max(bounds1.Right, bounds2.Right),
+ Math.Min(bounds1.Bottom, bounds2.Bottom),
+ Math.Max(bounds1.Top, bounds2.Top));
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/WaterBoard.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/WaterBoard.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/WaterBoard.cs (revision 334)
@@ -0,0 +1,181 @@
+// 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 System.Xml.Serialization;
+using Deltares.DamEngine.Data.Standard.Language;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class WaterBoard
+ {
+ private string description = "";
+ private IList dikes;
+ private List locations = null;
+ private IList segments;
+ private IList soilgeometry2DNames;
+ private string waterLevelTimeSeriesFileName;
+ private Dike selectedDike;
+
+ public WaterBoard()
+ {
+ this.dikes = new List();
+ this.segments = new List();
+ this.soilgeometry2DNames = new List();
+ }
+
+ public virtual IList Segments
+ {
+ get { return this.segments; }
+ set { this.segments = value; }
+ }
+
+ public virtual IList SoilGeometry2DNames
+ {
+ get { return this.soilgeometry2DNames; }
+ set { this.soilgeometry2DNames = value; }
+ }
+
+ public void FillGeometry2DNamesFromSegments()
+ {
+ // Add soilgeometry2D names into list
+ foreach (Segment segment in Segments)
+ {
+ foreach (SoilGeometryProbability soilGeometryProbability in segment.SoilProfileProbabilities)
+ {
+ if (soilGeometryProbability.SoilGeometry2DName != null && !SoilGeometry2DNamesContains(soilGeometryProbability.SoilGeometry2DName))
+ {
+ SoilGeometry2DName soilGeometry2DName = new SoilGeometry2DName();
+ soilGeometry2DName.Geometry2DName = soilGeometryProbability.SoilGeometry2DName;
+ SoilGeometry2DNames.Add(soilGeometry2DName);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Updates the locations for scenarios.
+ ///
+ public void UpdateLocationsForScenarios()
+ {
+ foreach (Dike dike in this.Dikes)
+ {
+ dike.UpdateLocationsForScenarios();
+ }
+ }
+
+ ///
+ /// Gets the selected dike.
+ /// Is a helper property to be able to show the soil table. When more Dikes than one are allowed,
+ /// this has to become a "real" property set by the onselectionchanged event.
+ ///
+ ///
+ /// The selected dike.
+ ///
+ public Dike SelectedDike
+ {
+ get
+ {
+ if (selectedDike != null)
+ {
+ return selectedDike;
+ }
+ return dikes.Count > 0 ? dikes[0] : null;
+ }
+ set
+ {
+ selectedDike = value;
+ }
+ }
+
+ private bool SoilGeometry2DNamesContains(string Name)
+ {
+ foreach (var soilGeometry2DName in SoilGeometry2DNames)
+ {
+ if (soilGeometry2DName.Geometry2DName == Name)
+ return true;
+ }
+ return false;
+ }
+
+ public virtual IList Dikes
+ {
+ get { return this.dikes; }
+ set { this.dikes = value; }
+ }
+
+ [XmlIgnore]
+ public List Locations
+ {
+ get
+ {
+ if (locations == null)
+ {
+ locations = new List();
+ foreach (Dike dike in this.Dikes)
+ {
+ locations.AddRange(dike.Locations);
+ }
+ }
+
+ return locations;
+ }
+ }
+
+ public virtual string NumberOfDikes
+ {
+ get { return this.dikes.Count.ToString(); }
+ }
+
+ public virtual string Name
+ {
+ get { return String.Format(LocalizationManager.GetTranslatedText(this, "WaterBoard")); }
+ }
+
+ public virtual string Description
+ {
+ get { return description; }
+ set { description = value; }
+ }
+
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ public string WaterLevelTimeSeriesFileName
+ {
+ get { return waterLevelTimeSeriesFileName; }
+ set
+ {
+ waterLevelTimeSeriesFileName = value;
+ }
+ }
+
+ public Segment GetSegmentByName(string segmentId)
+ {
+ Segment segment = this.segments.Where(x => ((x.Name == segmentId))).FirstOrDefault();
+ return segment;
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Properties/AssemblyInfo.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Properties/AssemblyInfo.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Properties/AssemblyInfo.cs (revision 334)
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Deltares.DamEngine.Data")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Deltares")]
+[assembly: AssemblyProduct("Deltares.DamEngine.Data")]
+[assembly: AssemblyCopyright("Copyright © Deltares 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("c984b656-9ece-4aef-ae46-6a1bb8023cfe")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("17.1.0.0")]
+[assembly: AssemblyFileVersion("17.1.0.0")]
Index: dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/HydraulicShortcutRWEvaluator.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/HydraulicShortcutRWEvaluator.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/HydraulicShortcutRWEvaluator.cs (revision 334)
@@ -0,0 +1,285 @@
+// 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 Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.PlLines;
+
+namespace Deltares.DamEngine.Data.RWScenarios
+{
+ public class HydraulicShortcutRWEvaluator : RWEvaluator
+ {
+ private const double cMinUpliftFactor = 1.2;
+ private const double cMinAquitardThickness = 2.0; // meter
+ private const double cMinHeadGradient = 1.0; // meter
+ private const double cMinAquitardThicknessIfDrySensitive = 5.0; // meter
+ private const double cMinClayThickness = 2.0; // meter
+ private DikeDrySensitivity dikeDrySensitivity = DikeDrySensitivity.None;
+ private LoadSituation loadSituation = LoadSituation.Wet;
+
+ public HydraulicShortcutRWEvaluator()
+ {
+ }
+
+ public override Enum Evaluate(Location location, SoilGeometry soilGeometry, params Enum[] previousChoices)
+ {
+ base.Evaluate(location, soilGeometry, previousChoices);
+ HydraulicShortcutType hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
+
+ // Determine dikeDrySensitivity and loadsituation
+ Dictionary choices = new Dictionary();
+ foreach (Enum enumValue in previousChoices)
+ {
+ if (enumValue != null)
+ {
+ choices[enumValue.GetType()] = enumValue;
+ }
+ }
+ dikeDrySensitivity = (DikeDrySensitivity)choices[typeof(DikeDrySensitivity)];
+ loadSituation = (LoadSituation)choices[typeof(LoadSituation)];
+ System.Diagnostics.Debug.Print(String.Format("==== Hydraulic shortcut evaluation of '{0}'", location.Name));
+ // determine hydraulic shortcut
+
+ // evaluate boezempeil (step 1)
+ if (EvaluateBoezemLevelBelowHeadAquifer())
+ {
+ hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
+ }
+ else
+ {
+ // Evaluate thickness of aquitard (step 2)
+ if (!EvaluateAquitardHasEnoughThickness())
+ {
+ hydraulicShortcutType = HydraulicShortcutType.HydraulicShortcut;
+ }
+ else
+ {
+ // Evaluate drysensitive dike (step 3)
+ if (!EvaluateDikeIsDrySensitive())
+ {
+ hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
+ }
+ else
+ {
+ // Evaluate thickness clay in aquitard and sheetpile (step 4)
+ if (EvaluateClayInAquitardTooThin())
+ {
+ if (loadSituation == LoadSituation.Dry)
+ {
+ hydraulicShortcutType = HydraulicShortcutType.HydraulicShortcut;
+ }
+ else
+ {
+ hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
+ }
+ }
+ else
+ {
+ hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
+ }
+ }
+ }
+ }
+
+ System.Diagnostics.Debug.Print(String.Format("==== End of Hydraulic shortcut evalution of '{0}'", location.Name));
+ return hydraulicShortcutType;
+ }
+
+ ///
+ /// Condition: Dikte waterremmende laag minstens 2 meter
+ ///
+ ///
+ private bool EvaluateAquitardHasEnoughThickness()
+ {
+ var aquitardEvaluator = new AquitardEvaluator(soilGeometry.SoilProfile);
+ double aquitardTichkness = aquitardEvaluator.DetermineAquitardThicknessWithMinimalWeight(location.DredgingDepth, this.location.GetDikeEmbankmentSoil()); // Note: do not evaluate sheetpile here
+ bool aquitardHasEnoughThickness = (aquitardTichkness >= cMinAquitardThickness);
+ System.Diagnostics.Debug.Print(String.Format("Aquitard thickness ({0}) sufficient is {1}; it should be more than {2} meter",
+ aquitardTichkness, aquitardHasEnoughThickness , cMinAquitardThickness));
+ return aquitardHasEnoughThickness;
+ }
+
+ ///
+ /// Condition: Droogtegevoeilige kade
+ ///
+ ///
+ private bool EvaluateDikeIsDrySensitive()
+ {
+ // Evaluate dry sensivity of dike
+ // with uplift calculation the pl-lines will be created different when dikematerial is of type peat
+ bool isDrySensitive = (dikeDrySensitivity == DikeDrySensitivity.Dry);
+ System.Diagnostics.Debug.Print(String.Format("Is dry sensitive dike is {0} (check on material)", isDrySensitive));
+ if (isDrySensitive)
+ {
+ double gradient = (GetBoezemLevel() - location.PolderLevelLow);
+ isDrySensitive = gradient > cMinHeadGradient;
+ System.Diagnostics.Debug.Print(String.Format("Is dry sensitive dike is {0} because Gradient in dike ({1}) more than {2} meter", isDrySensitive, gradient, cMinHeadGradient));
+ }
+ if (isDrySensitive)
+ {
+ double? upliftFactor = 0.0;
+
+ // upliftFactor = GetLowestUpliftFactor(); ## Bka
+ if (upliftFactor != null)
+ {
+ isDrySensitive = (upliftFactor.Value < cMinUpliftFactor);
+ System.Diagnostics.Debug.Print(String.Format("Is dry sensitive dike is {0} because upliftfactor ({1}) more than {2}", isDrySensitive, upliftFactor.Value, cMinUpliftFactor));
+ }
+ else
+ {
+ isDrySensitive = false;
+ }
+ }
+ return isDrySensitive;
+ }
+
+ ///
+ /// Condition: Dikte kleilaag in waterremmende laag kleiner 2 meter of dikte waterremmende kleiner 5 meter
+ ///
+ ///
+ private bool EvaluateClayInAquitardTooThin()
+ {
+ var aquitardEvaluator = new AquitardEvaluator(soilGeometry.SoilProfile);
+ double aquitardThicknessWithoutMinimalWeight = aquitardEvaluator.DetermineAquitardThicknessWithoutMinimalWeight(GetBoezemBottomOrSheetPileBottom(), this.location.GetDikeEmbankmentSoil());
+ double claythickness = aquitardEvaluator.DetermineAquitardClayThickness(GetBoezemBottomOrSheetPileBottom());
+
+ bool clayInAquitardTooThin = (aquitardThicknessWithoutMinimalWeight < cMinAquitardThicknessIfDrySensitive);
+ clayInAquitardTooThin = clayInAquitardTooThin || (claythickness < cMinClayThickness);
+
+ System.Diagnostics.Debug.Print(String.Format("For dry sensitive dike aquitard thickness ({0} < {1}) or clay thickness ({2} < {3}) evaluate to {4}",
+ aquitardThicknessWithoutMinimalWeight, cMinAquitardThicknessIfDrySensitive, claythickness, cMinClayThickness, clayInAquitardTooThin));
+ return clayInAquitardTooThin;
+ }
+
+ ///
+ /// Condition: Boezempeil kleiner of gelijk aan stijghoogte eerste WVP
+ ///
+ ///
+ private bool EvaluateBoezemLevelBelowHeadAquifer()
+ {
+ double boezemLevel = GetBoezemLevel();
+ bool boezemLevelBelowHeadAquifer = boezemLevel <= location.HeadPl3;
+ System.Diagnostics.Debug.Print(String.Format("Storage basin level ({0}) below head Aquifer WVP ({1}) is {2}", boezemLevel, location.HeadPl3, boezemLevelBelowHeadAquifer));
+ return boezemLevelBelowHeadAquifer;
+ }
+
+ private double GetBoezemBottomOrSheetPileBottom()
+ {
+ double boezemBottom = location.DredgingDepth;
+ if (location.SheetPileLength > 0)
+ {
+ double rwBankProtectionBottomLevel = location.RwBankProtectionBottomLevel;
+ boezemBottom = Math.Min(boezemBottom, rwBankProtectionBottomLevel);
+ //// sheetpile is available
+ //if (location.LocalXZSheetPilePoint.X < location.LocalXZSurfaceLine.CharacteristicPoints[CharacteristicPointType.DikeTopAtRiver].X)
+ //{
+ // double sheetpilePointLevel = location.LocalXZSheetPilePoint.Z - location.SheetPileLength;
+ // boezemBottom = Math.Min(boezemBottom, sheetpilePointLevel);
+ //}
+ //else
+ //{
+ // System.Diagnostics.Debug.Print(String.Format("Ignored sheetpile because X sheetpile ({0}) is larger than X dike crest at river ({1})",
+ // location.LocalXZSheetPilePoint.X, location.LocalXZSurfaceLine.CharacteristicPoints[CharacteristicPointType.DikeTopAtRiver].X));
+ //}
+ }
+ return boezemBottom;
+ }
+
+ ///
+ /// Determine boezemlevel according to loadsituation
+ ///
+ ///
+ private double GetBoezemLevel()
+ {
+ double boezemLevel = 0.0;
+ switch (loadSituation)
+ {
+ case LoadSituation.Wet:
+ boezemLevel = location.BoezemLevelTp;
+ break;
+ case LoadSituation.Dry:
+ boezemLevel = location.BoezemLevelHbp;
+ break;
+ }
+ return boezemLevel;
+ }
+
+ ///
+ /// 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;
+//
+// 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;
+// }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs (revision 334)
@@ -0,0 +1,157 @@
+// 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.Collections.Generic;
+using System.Xml.Serialization;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Dataclass for the geometryloop.
+ ///
+ ///
+ public class GeometryLoop : GeometryPointString
+ {
+ private readonly List curveList = new List();
+
+ ///
+ /// Gets the List of all Curves.
+ ///
+ public List CurveList
+ {
+ get
+ {
+ return curveList;
+ }
+ }
+
+ ///
+ /// List of points that describe the physical surface line or surface.
+ ///
+ /// This property is not serialized. If you want to add point definitions,
+ /// do so by adding/inserting a new element to .
+ [XmlIgnore]
+ public override List CalcPoints
+ {
+ get
+ {
+ // explicit use of protected field to prevent stack overflow due to recursive call
+ if (calcPoints.Count == 0)
+ {
+ PopulateLoopPointList();
+ SyncPoints();
+ }
+
+ return calcPoints;
+ }
+ }
+
+ ///
+ /// Determines whether this instance is loop.
+ ///
+ ///
+ public bool IsLoop()
+ {
+ if (CurveList.Count <= 2)
+ {
+ return false;
+ }
+
+ GeometryCurve beginCurve = curveList[0];
+ GeometryCurve endCurve = curveList[curveList.Count - 1];
+
+ if (beginCurve.HeadPoint == endCurve.HeadPoint ||
+ beginCurve.HeadPoint == endCurve.EndPoint ||
+ beginCurve.EndPoint == endCurve.HeadPoint ||
+ beginCurve.EndPoint == endCurve.EndPoint)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// See if a point lies in a closed surface
+ ///
+ ///
+ ///
+ public bool IsPointInLoopArea(Point2D aPoint)
+ {
+ return Routines2D.CheckIfPointIsInPolygon(this, aPoint.X, aPoint.Z) != PointInPolygon.OutsidePolygon;
+ }
+
+ ///
+ /// Populates the loop's GeometryPoint list.
+ ///
+ private void PopulateLoopPointList()
+ {
+ // explicit use of protected field to prevent stack overflow due to recursive call
+ if (calcPoints.Count > 0)
+ {
+ return;
+ }
+ for (int index = 0; index < curveList.Count; index++)
+ {
+ if (index == 0)
+ {
+ calcPoints.Add(curveList[index].HeadPoint);
+ calcPoints.Add(curveList[index].EndPoint);
+ }
+ else
+ {
+ // TODO why not compare by value instead of reference
+ if (curveList[index].HeadPoint == calcPoints[calcPoints.Count - 1])
+ {
+ calcPoints.Add(curveList[index].EndPoint);
+ }
+ else if (curveList[index].EndPoint == calcPoints[calcPoints.Count - 1])
+ {
+ calcPoints.Add(curveList[index].HeadPoint);
+ }
+ else
+ {
+ if (calcPoints.Count == 2)
+ {
+ calcPoints.Reverse();
+ }
+ if (curveList[index].HeadPoint == calcPoints[calcPoints.Count - 1])
+ {
+ calcPoints.Add(curveList[index].EndPoint);
+ }
+ else if (curveList[index].EndPoint == calcPoints[calcPoints.Count - 1])
+ {
+ calcPoints.Add(curveList[index].HeadPoint);
+ }
+ }
+ }
+ }
+
+ if (calcPoints.Count > 0)
+ {
+ if (calcPoints[0] == calcPoints[calcPoints.Count - 1])
+ {
+ calcPoints.RemoveAt(calcPoints.Count - 1);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPoint.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPoint.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryPoint.cs (revision 334)
@@ -0,0 +1,189 @@
+// 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.ComponentModel;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Class to manage a geometry point.
+ ///
+ [Serializable]
+ [TypeConverter(typeof(ExpandableObjectConverter))]
+ public class GeometryPoint : GeometryObject, ICloneable, IComparable
+ {
+ ///
+ /// The precision
+ ///
+ public const double Precision = GeometryConstants.Accuracy;
+
+ private object owner;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GeometryPoint() : this(0.0, 0.0) {}
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A point.
+ public GeometryPoint(GeometryPoint aPoint) : this(aPoint.X, aPoint.Z) {}
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A x.
+ /// A z.
+ public GeometryPoint(double aX, double aZ)
+ {
+ X = aX;
+ Z = aZ;
+ }
+
+ ///
+ /// Gets or sets the X coordinate of GeometryPoint
+ ///
+ public virtual double X { get; set; }
+
+ ///
+ /// Gets or sets the Y coordinate of GeometryPoint
+ ///
+ public virtual double Y { get; set; }
+
+ ///
+ /// Gets or sets the Z coordinate of GeometryPoint
+ ///
+ public virtual double Z { get; set; }
+
+ ///
+ /// Identifies the object which owns this point.
+ ///
+ ///
+ /// Usually set by a delegated list, such as in .
+ ///
+ [XmlIgnore]
+ public object Owner
+ {
+ get
+ {
+ return owner;
+ }
+ set
+ {
+ owner = value;
+ }
+ }
+
+ ///
+ /// Determines whether the location of the given point and this one are the same.
+ ///
+ /// The other.
+ ///
+ public bool LocationEquals(GeometryPoint other)
+ {
+ return LocationEquals(other, Precision);
+ }
+
+ ///
+ /// Determines whether the difference between the location of the given point and
+ /// this one are within the given precision.
+ ///
+ /// The other.
+ /// The precision.
+ ///
+ public bool LocationEquals(GeometryPoint other, double precision)
+ {
+ if (ReferenceEquals(other, null))
+ {
+ return false;
+ }
+ if (ReferenceEquals(other, this))
+ {
+ return true;
+ }
+
+ return X.AlmostEquals(other.X, precision) &&
+ Z.AlmostEquals(other.Z, precision);
+ }
+
+ ///
+ /// Gets the geometry bounds.
+ ///
+ ///
+ public override GeometryBounds GetGeometryBounds()
+ {
+ return new GeometryBounds(X, X, Z, Z);
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return "(" + X.ToString("F3") + ";" + Z.ToString("F3") + ")";
+ }
+
+
+
+ #region ICloneable Members
+
+ ///
+ /// Clones this instance.
+ ///
+ /// Only copies and .
+ public virtual object Clone()
+ {
+ return new GeometryPoint(this);
+ }
+
+ #endregion
+
+ #region IComparable Members
+
+ ///
+ /// Compares the current instance with another object of the same type
+ /// Eventhough this method does not seem to be used it is! (via GPstring which is a delegated list, using a Sort which needs this).
+ /// So do NOT delete this as long as GPS stays a delegated list.
+ ///
+ /// An object to compare with this instance.
+ ///
+ /// Result of comparing the X values
+ ///
+ public int CompareTo(object obj)
+ {
+ var point = obj as GeometryPoint;
+ if (point != null)
+ {
+ return X.CompareTo(point.X);
+ }
+ return ToString().CompareTo(obj.ToString());
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorFactory.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorFactory.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorFactory.cs (revision 334)
@@ -0,0 +1,63 @@
+// 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 Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.General.Sensors
+{
+ public class SensorFactory
+ {
+ ///
+ /// Creates a sensor location.
+ ///
+ /// The location.
+ ///
+ internal SensorLocation CreateSensorLocation(Location location)
+ {
+ return CreateSensorLocation(location, new Group());
+ }
+
+ ///
+ /// Creates a sensor location.
+ ///
+ /// The location.
+ /// The group to associate the location with
+ /// Should return a valid instance
+ internal SensorLocation CreateSensorLocation(Location location, Group group)
+ {
+ return new SensorLocation
+ {
+ Group = group,
+ Location = location,
+ PL1WaterLevelAtRiver = DataSourceTypeSensors.LocationData,
+ PL1PLLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.LocationData,
+ PL1PLLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.LocationData,
+ PL1PLLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData,
+ PL1PLLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.LocationData,
+ PL1WaterLevelAtPolder = DataSourceTypeSensors.LocationData,
+ PL3 = DataSourceTypeSensors.LocationData,
+ PL4 = DataSourceTypeSensors.LocationData
+ };
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/SoilGeometry.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/SoilGeometry.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/SoilGeometry.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Data/General/DAMEnumerations.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/DAMEnumerations.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/DAMEnumerations.cs (revision 334)
@@ -0,0 +1,396 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public enum DamLicenseType
+ {
+ None = 0,
+ Dongle = 1,
+ FlexNet = 2,
+ FlexLm = 3,
+ LicFile = 4,
+ LFM = 5
+ }
+
+ public enum DamType
+ {
+ Primary,
+ Regional
+ }
+
+ public enum FullAnalysisType
+ {
+ Normal,
+ WV21
+ };
+
+ public enum DamProjectType
+ {
+ Calamity,
+ Assessment,
+ Design,
+ DamLiveConfiguration
+ }
+
+ public enum ProgramType
+ {
+ MStab,
+ SlopeW
+ };
+
+ public enum StabilityKernelType
+ {
+ // The Classic models all use DGMStabDam.dll to generate a sti file from the input (so also pl-lines only)
+ // DAM classic uses the Delphi version of DGS (as exe) to solve the calculation
+ DamClassic,
+
+ // DAM classic .Net uses the .Net version of DGS which is based on the old Delphi code to solve the calculation
+ DamClassicDotNet,
+
+ // DAM classic WTI uses the .Net version of DGS which is based on the new C# code to solve the calculation
+ DamClassicWti,
+
+ // The advanced models use the geotechnics and DGS classes to generate the required data from input,
+ // using the waternet only. This requires the -rto option for starting
+ // Advanced .Net uses the .Net version of DGS which is based on the old Delphi code to solve the calculation
+ AdvancedDotNet,
+
+ // Advanced WTI uses the .Net version of DGS which is based on the new C# code to solve the calculation
+ AdvancedWti
+ };
+
+ public enum AnalysisType
+ {
+ NoAdaption,
+ AdaptGeometry,
+ AdaptNWO
+ };
+
+ public enum ProbabilisticType
+ {
+ Deterministic,
+ Probabilistic,
+ ProbabilisticFragility
+ };
+
+ public enum FailureMechanismSystemType
+ {
+ StabilityInside,
+ StabilityOutside,
+ Piping,
+ HorizontalBalance,
+ FlowSlide
+ }
+
+ public enum MStabModelType
+ {
+ Bishop,
+ Spencer,
+ Fellenius,
+ UpliftVan,
+ UpliftSpencer,
+ BishopRandomField,
+ HorizontalBalance,
+ BishopUpliftVan,
+ SpencerHigh, // #Bka added SpencerHigh/SpencerLow as quick fix. Should be replaced with options for Spencer later! These enums should be removed.
+ SpencerLow
+ }
+
+ public enum PipingModelType
+ {
+ Bligh,
+ Sellmeijer,
+ Sellmeijer2Forces,
+ Sellmeijer4Forces,
+ Wti2017
+ };
+
+ public enum FlowSlideModelType
+ {
+ All,
+ };
+
+ public enum PLLineAssignment
+ {
+ NoPLLines,
+ ExpertKnowledge,
+ DikeFlow,
+ OrginalPLLines
+ }
+
+ public enum SoilGeometryType
+ {
+ SoilGeometry1D,
+ SoilGeometry2D
+ }
+
+
+
+ public enum MStabShearStrength
+ {
+ CPhi,
+ StressTables,
+ CuCalculated,
+ CuMeasured,
+ CuGradient,
+ Default
+ }
+
+ public enum MStabSearchMethod
+ {
+ Grid,
+ GeneticAlgorithm
+ }
+
+ public enum MStabGridPosition
+ {
+ Left,
+ Right
+ }
+
+ public enum MStabZonesType
+ {
+ NoZones = 0,
+ ZoneAreas = 1,
+ ForbiddenZone = 2
+ }
+
+ public enum NonWaterRetainingObjectCategory
+ {
+ Tree,
+ Main
+ };
+
+ public enum NonWaterRetainingObjectType
+ {
+ Oak,
+ Alder,
+ Poplar,
+ GasMain,
+ WaterMain
+ };
+
+ public enum StabilityDesignMethod //Design
+ {
+ OptimizedSlopeAndShoulderAdaption,
+ SlopeAdaptionBeforeShoulderAdaption
+ }
+
+ public enum PhreaticAdaptionType //NWO
+ {
+ None,
+ MakeEmpty,
+ Fill // Note: Fill not yet implemented!
+ } ;
+
+ public enum PLLineType
+ {
+ PL1,
+ PL2,
+ PL3,
+ PL4
+ }
+
+ public enum PLLinePointPositionXzType
+ {
+ OnPLLine,
+ AbovePLLine,
+ BelowPLLine,
+ BeyondPLLine // indicates that point is outside the scope of the pl line.
+ };
+
+ public enum DikeDrySensitivity //RWScenarios
+ {
+ None,
+ Dry
+ }
+
+ public enum HydraulicShortcutType //RWScenarios
+ {
+ HydraulicShortcut,
+ NoHydraulicShortcut
+ }
+
+ public enum RWResultType //RWScenarios
+ {
+ ProbabilityOfFailure,
+ SafetyFactor
+ }
+
+ public enum ResultEvaluation //RWScenarios
+ {
+ Accepted,
+ Rejected,
+ NotEvaluated
+ }
+
+ public enum LoadSituation //RWScenarios
+ {
+ Dry,
+ Wet
+ }
+
+ public enum ScenarioType //RWScenarios
+ {
+ Scenario01 = 1,
+ Scenario02 = 2,
+ Scenario03 = 3,
+ Scenario04 = 4,
+ Scenario05 = 5,
+ Scenario06 = 6,
+ Scenario07 = 7,
+ Scenario08 = 8,
+ Scenario09 = 9,
+ Scenario10 = 10,
+ Scenario11 = 11
+ }
+
+ public enum SchematizationType //Schematizationfactor
+ {
+ MacroStabiltyInnerSideWet,
+ MacroStabiltyInnerSideDry,
+ PipingWet,
+ PipingDry,
+ HorzontalBalanceDry
+ }
+
+ public enum DataSourceTypeSensors //Sensors
+ {
+ Ignore,
+ LocationData,
+ Sensor
+ }
+
+ public enum SensorType //Sensors
+ {
+ PiezometricHead,
+ WaterLevel,
+ PolderLevel
+ }
+
+ ///
+ /// Type of output series
+ ///
+ public enum TimeSerieParameters
+ {
+ [Obsolete("Use StabilityInsideFactor instead")]
+ SafetyFactor, // <- Is same as StabilityInsideFactor, kept for legacy code
+ PipingFactorWti,
+ PipingFactorBligh,
+ PipingFactorSellmeijer,
+ ProbabilityOfFailurePipingSellmeijer,
+ OvertoppingErosion,
+ StabilityInsideFactor,
+ StabilityOutsideFactor
+ }
+
+ public enum UpliftType
+ {
+ Uplift,
+ NoUplift
+ }
+
+ public enum PLLineCreationMethod
+ {
+ ExpertKnowledgeRRD,
+ ExpertKnowledgeLinearInDike,
+ GaugesWithFallbackToExpertKnowledgeRRD,
+ DupuitStatic,
+ DupuitDynamic,
+ Sensors,
+ None
+ }
+
+ public enum ProjectPathLocation
+ {
+ // Other future possibilties: InProjectMap, InWindowsTemp
+ InApplicationMap,
+ InUserMap,
+ InProjectMap
+ }
+
+ public enum StabMethodDupuit
+ {
+ None = 0,
+ Fellenius = 1,
+ Bishop = 2
+ }
+
+ public enum DataSourceType
+ {
+ CsvFiles,
+ Iris,
+ DataShapeFiles,
+ BackgroundShapeFiles,
+ MSoilBase,
+ MGeobase
+ }
+
+ public enum LayerType
+ {
+ Top,
+ Dike,
+ Cover,
+ Aquifer1,
+ Aquifer2,
+ Aquitard
+ }
+
+ public enum JobResult
+ {
+ NoRun,
+ Failed,
+ Good,
+ Bad,
+ Mixed
+ }
+
+ public enum TimeStepUnit
+ {
+ Second,
+ Minute,
+ Hour,
+ Day,
+ Week,
+ Month,
+ Year,
+ Nonequidistant
+ }
+
+ public enum ConfigurationStatus
+ {
+ Available, // Option is implemented and available
+ NotAvailable, // Option is implemented and available (can be used when combination is in development, so it will be hidden)
+ NotImplemented // Option is not implemented (so also no available)
+ }
+
+ public enum IntrusionVerticalWaterPressureType
+ {
+ Standard,
+ Linear,
+ FullHydroStatic,
+ HydroStatic,
+ SemiTimeDependent
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/General/RequiredEntityNotExistException.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/General/RequiredEntityNotExistException.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/General/RequiredEntityNotExistException.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Data/General/Sensors/Sensor.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Sensor.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Sensor.cs (revision 334)
@@ -0,0 +1,324 @@
+// 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.Standard;
+
+namespace Deltares.DamEngine.Data.General.Sensors
+{
+ ///
+ /// This class represents a sensor or monitoring point used in dikes.
+ /// This entity is created for Dam Live
+ ///
+ public class Sensor : IName
+ {
+ #region Business Rules
+
+ ///
+ /// Specication to test if the value of the candidate is valid
+ ///
+// internal class ContiansAtLeastOneItem : PredicateSpecification>
+// {
+// public ContiansAtLeastOneItem()
+// : base(x => x.Any())
+// {
+// Description = "The sensor should contain at least one PL Line mapping.";
+// }
+// }
+
+ #endregion
+
+ //private readonly IGeometry geometry;
+ private double relativeLocation;
+ private readonly HashSet plLineTypes;
+ private int id;
+ private double xRd;
+ private double yRd;
+ private double zRd;
+
+ public Sensor()
+ {
+ plLineTypes = new HashSet();
+ ID = -1;
+ //geometry = new Point(0,0,0);
+ }
+
+// public Sensor(Point point) : this()
+// {
+// if (point == null) throw new ArgumentNullException("point");
+// //this.geometry = point;
+//
+// }
+
+ public Sensor(double x, double y, double z) //: this(new Point(x, y, z))
+ {
+ xRd = x;
+ yRd = y;
+ zRd = z;
+ }
+
+ ///
+ /// Gets or sets the ID.
+ ///
+ ///
+ /// The ID should be unique.
+ ///
+ public int ID
+ {
+ get { return id; }
+ set
+ {
+ id = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the name of this sensor.
+ ///
+ ///
+ /// The name string value should not be empty and unique.
+ ///
+ // [Specification(typeof(NotEmptySpecification))]
+ public string Name { get; set; }
+
+ ///
+ /// Gets or sets the depth.
+ ///
+ ///
+ /// The depth.
+ ///
+ public double Depth
+ {
+ get { return ZRd; }
+ set
+ {
+ ZRd = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the relative location along the profile.
+ ///
+ ///
+ /// The relative location in meter.
+ ///
+ public double RelativeLocation
+ {
+ get { return relativeLocation; }
+ set
+ {
+ relativeLocation = value;
+ RelativeLocationSpecified = true;
+ }
+ }
+
+ ///
+ /// Gets or sets the X rd.
+ ///
+ ///
+ /// The X rd.
+ ///
+ public double XRd
+ {
+ get { return xRd; }
+ set { xRd = value; }
+ }
+
+ ///
+ /// Gets or sets the Y rd.
+ ///
+ ///
+ /// The Y rd.
+ ///
+ public double YRd
+ {
+ get { return yRd; }
+ set { yRd = value; }
+ }
+
+ ///
+ /// Gets or sets the Z rd. Same as Depth??
+ ///
+ ///
+ /// The Z rd.
+ ///
+ public double ZRd
+ {
+ get { return zRd; }
+ set { zRd = value; }
+ }
+
+ ///
+ /// Gets a value indicating whether the relative location is specified.
+ ///
+ ///
+ /// true if the relative location is specified; otherwise, false.
+ ///
+ public bool RelativeLocationSpecified { get; private set; }
+
+ private SensorType type;
+
+ ///
+ /// Gets or sets the type of this sensor.
+ ///
+ ///
+ /// The type. Default value is PiezoMetricHead.
+ ///
+ public SensorType Type
+ {
+ get { return type; }
+ set { type = value; }
+ }
+
+ ///
+ /// Gets or sets the PL line array. Used for serialization only.
+ ///
+ ///
+ /// The PL line array.
+ ///
+ // [Specification(typeof(NotNullSpecification))]
+ // [Specification(typeof(ContiansAtLeastOneItem))]
+ public PLLineType[] PLLineMappings
+ {
+ get { return plLineTypes.ToArray(); }
+ set
+ {
+ ClearPLLines();
+ foreach (var lineType in value)
+ {
+ Add(lineType);
+ }
+ }
+ }
+
+ public string PLLineMappingsAsString
+ {
+ get
+ {
+ string res = "";
+ foreach (var plLineType in plLineTypes)
+ {
+ switch (plLineType)
+ {
+ case PLLineType.PL1: res = res + "1; "; break;
+ case PLLineType.PL2: res = res + "2; "; break;
+ case PLLineType.PL3: res = res + "3; "; break;
+ case PLLineType.PL4: res = res + "4; "; break;
+ }
+ }
+ return res;
+ }
+ set
+ {
+ ClearPLLines();
+ var locPlLineTypes = ParseStringToPlLineTypes(value);
+ foreach (var plLineType in locPlLineTypes)
+ {
+ switch (plLineType)
+ {
+ case 1: plLineTypes.Add(PLLineType.PL1); break;
+ case 2: plLineTypes.Add(PLLineType.PL2); break;
+ case 3: plLineTypes.Add(PLLineType.PL3); break;
+ case 4: plLineTypes.Add(PLLineType.PL4); break;
+ }
+ }
+ }
+ }
+
+ private List ParseStringToPlLineTypes(string value)
+ {
+ value = value.Trim();
+ var ids = new List();
+ var idsarr = value.Split(new Char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
+ foreach (var s in idsarr)
+ {
+ try
+ {
+ var val = Int32.Parse(s);
+ ids.Add(val);
+ }
+ catch (Exception)
+ {
+ // surpress errors, just do not use value
+ }
+ }
+ return ids;
+ }
+
+ ///
+ /// Adds the specified PL line.
+ ///
+ /// The PL line.
+ public void Add(PLLineType plLine)
+ {
+ plLineTypes.Add(plLine);
+ }
+
+ ///
+ /// Removes the specified PL line.
+ ///
+ /// The PL line.
+ public void Remove(PLLineType plLine)
+ {
+ plLineTypes.Remove(plLine);
+ }
+
+ ///
+ /// Clears the PL lines list.
+ ///
+ public void ClearPLLines()
+ {
+ plLineTypes.Clear();
+ }
+
+ ///
+ /// Determines whether this instance is valid.
+ ///
+ ///
+ /// true if this instance is valid; otherwise, false.
+ ///
+// public bool IsValid()
+// {
+// return !Validator.Validate(this).Any();
+// }
+
+ ///
+ /// Determines whether this instance is transient (associated with a correct ID in the context of the repository).
+ ///
+ ///
+ /// true if this instance is transient; otherwise, false.
+ ///
+ public bool IsTransient()
+ {
+ return ID < 0;
+ }
+
+ public override string ToString()
+ {
+ var name = string.IsNullOrWhiteSpace(Name) ? "name_not_set" : Name;
+
+ return string.Format("[ID: {0}, Name: {1}, Depth: {2}, Type: {3}, RelativeLocation: {4}]",
+ ID, name, Depth, Type, RelativeLocation);
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityServiceAgent.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityServiceAgent.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityServiceAgent.cs (revision 334)
@@ -0,0 +1,585 @@
+// 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.Diagnostics;
+using System.IO;
+using System.Text;
+using System.Threading;
+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.Calculators.Stability
+{
+ ///
+ /// Defines the service agent which is responsible for delegating calls
+ /// to the MStab calculation kernel or services
+ ///
+ public class StabilityServiceAgent : IDisposable
+ {
+ private DGSMStabDAMInterface mstabDamDll;
+ private DGSDAMSlopeWInterface slopeWDamDll;
+
+ public StabilityServiceAgent()
+ {
+ mstabDamDll = new DGSMStabDAMInterface();
+ slopeWDamDll = new DGSDAMSlopeWInterface();
+ MStabExePath = DamProjectData.MStabExePath;
+ SlopeWExePath = DamProjectData.SlopeWExePath;
+ }
+
+ #region Native Members
+
+ ///
+ /// Constant to the dll file can only be a constant!
+ ///
+
+ #endregion
+
+ #region Wrapper Methods
+
+ public string MStabExePath { get; set; }
+ public string SlopeWExePath { get; set; }
+ public ProgramType ProgramType { get; set; }
+
+ ///
+ /// Get DLL version
+ ///
+ ///
+ public string GetDllVersion()
+ {
+ if (ProgramType == ProgramType.SlopeW)
+ {
+ return slopeWDamDll.GetDllVersion();
+ }
+ else
+ {
+ return mstabDamDll.GetDllVersion();
+ }
+ }
+
+ ///
+ /// Create MStab project file
+ ///
+ ///
+ public void CreateProjectFile(string inputXmlString)
+ {
+ lock (typeof (StabilityServiceAgent))
+ {
+ var result = 0;
+ if (ProgramType == ProgramType.SlopeW)
+ {
+ result = slopeWDamDll.CreateProjectFile(inputXmlString);
+ if (result > 0)
+ {
+ string errorMessage = slopeWDamDll.ErrorMessage();
+ throw new StabilityServiceAgentException(errorMessage);
+ }
+ }
+ else
+ {
+ result = mstabDamDll.CreateProjectFile(inputXmlString);
+ if (result > 0)
+ {
+ string errorMessage = mstabDamDll.ErrorMessage();
+ throw new StabilityServiceAgentException(errorMessage);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Create Soilprofile for location X in geometry-2d
+ ///
+ ///
+ ///
+ public void ConvertGeometry2DTo1D(string inputXML, ref StringBuilder outputXML)
+ {
+ const int defaultBufferSize = 10000;
+ int bufferSize = defaultBufferSize;
+ outputXML = new StringBuilder(bufferSize);
+ int returnCode = mstabDamDll.Geometry2DTo1DConversion(inputXML, outputXML, ref bufferSize);
+ if (returnCode == DgsStandardDllInterface.DllErrorOutputBufferTooSmall)
+ {
+ outputXML = new StringBuilder(bufferSize);
+ returnCode = mstabDamDll.Geometry2DTo1DConversion(inputXML, outputXML, ref bufferSize);
+ }
+ if (returnCode != DgsStandardDllInterface.DllErrorNone)
+ throw new StabilityServiceAgentException(mstabDamDll.ErrorMessage());
+ }
+
+ ///
+ /// Create Geometry2DData object from geometry2D file
+ ///
+ ///
+ ///
+ public void CreateGeometry2DDataFromGeometry2D(string inputXML, ref StringBuilder outputXML)
+ {
+ const int defaultBufferSize = 10000;
+ int bufferSize = defaultBufferSize;
+ outputXML = new StringBuilder(bufferSize);
+ int returnCode = mstabDamDll.CreateGeometry2DDataFromGeometry2D(inputXML, outputXML, ref bufferSize);
+ if (returnCode == DgsStandardDllInterface.DllErrorOutputBufferTooSmall)
+ {
+ outputXML = new StringBuilder(bufferSize);
+ returnCode = mstabDamDll.CreateGeometry2DDataFromGeometry2D(inputXML, outputXML, ref bufferSize);
+ }
+ if (returnCode != DgsStandardDllInterface.DllErrorNone)
+ throw new StabilityServiceAgentException(mstabDamDll.ErrorMessage());
+ }
+
+ ///
+ /// Calculate piping length
+ ///
+ ///
+ ///
+ public double CalculatePipingLength(PolyLine headLine)
+ {
+ int pointCount = headLine.Points.Count;
+ var headLinePoints = new DGSMStabDAMInterface.LegacyCoordinate[pointCount];
+ double[] pointCoordinates = new double[pointCount * 2];
+ for (int pointIndex = 0; pointIndex < pointCount; pointIndex++)
+ {
+ headLinePoints[pointIndex].x = headLine.Points[pointIndex].X;
+ headLinePoints[pointIndex].z = headLine.Points[pointIndex].Z;
+ pointCoordinates[pointIndex * 2] = headLine.Points[pointIndex].X;
+ pointCoordinates[pointIndex * 2 + 1] = headLine.Points[pointIndex].Z;
+ }
+ return mstabDamDll.PipingLengthCalculation(pointCount, ref headLinePoints);
+ }
+
+ ///
+ /// Calculate MStab projects in specified directory
+ ///
+ ///
+ public void CalculateMStabDirectory(string directoryPath)
+ {
+ ThrowHelper.ThrowIfStringArgumentNullOrEmpty(directoryPath, StringResourceNames.ProjectFileNameNullOrEmpty);
+ ThrowHelper.ThrowIfDirectoryNotExist(directoryPath, StringResourceNames.ProjectFileNotExist);
+ ThrowHelper.ThrowIfFileNotExist(MStabExePath, StringResourceNames.MStabExecutableFileNameNotFound);
+
+ try
+ {
+ // Compute the project files
+ ProcessInputfFile(directoryPath);
+ }
+ catch (ArgumentNullException argumentNullException)
+ {
+ throw new StabilityServiceAgentException(argumentNullException.Message, argumentNullException);
+ }
+ catch (FileNotFoundException outputFileNotFoundException)
+ {
+ throw new StabilityServiceAgentException(outputFileNotFoundException.Message, outputFileNotFoundException);
+ }
+ }
+
+ ///
+ /// Calculate MStab project
+ ///
+ ///
+ public void CalculateMStabProject(string projectFilePath)
+ {
+ ThrowHelper.ThrowIfStringArgumentNullOrEmpty(projectFilePath, StringResourceNames.ProjectFileNameNullOrEmpty);
+ ThrowHelper.ThrowIfFileNotExist(projectFilePath, StringResourceNames.ProjectFileNotExist);
+ ThrowHelper.ThrowIfFileNotExist(MStabExePath, StringResourceNames.MStabExecutableFileNameNotFound);
+
+ try
+ {
+ // Compute the project files
+ ProcessInputfFile(projectFilePath);
+ }
+ catch (ArgumentNullException argumentNullException)
+ {
+ throw new StabilityServiceAgentException(argumentNullException.Message, argumentNullException);
+ }
+ catch (FileNotFoundException outputFileNotFoundException)
+ {
+ throw new StabilityServiceAgentException(outputFileNotFoundException.Message, outputFileNotFoundException);
+ }
+ }
+
+ ///
+ /// Calculate SlopeW project
+ ///
+ ///
+ public void CalculateSlopeWProject(string projectFilePath)
+ {
+ ThrowHelper.ThrowIfStringArgumentNullOrEmpty(projectFilePath, StringResourceNames.ProjectFileNameNullOrEmpty);
+ ThrowHelper.ThrowIfFileNotExist(projectFilePath, StringResourceNames.ProjectFileNotExist);
+ ThrowHelper.ThrowIfFileNotExist(SlopeWExePath, StringResourceNames.SlopeWExecutableFileNameNotFound);
+
+ try
+ {
+ // Compute the project files
+ ProcessInputfFile(projectFilePath);
+ }
+ catch (ArgumentNullException argumentNullException)
+ {
+ throw new StabilityServiceAgentException(argumentNullException.Message, argumentNullException);
+ }
+ catch (FileNotFoundException outputFileNotFoundException)
+ {
+ throw new StabilityServiceAgentException(outputFileNotFoundException.Message, outputFileNotFoundException);
+ }
+ }
+
+ ///
+ /// Extracts the relevant calculation results from the outputfile of MStab
+ ///
+ /// The project file to process
+ /// The MStab calculation results
+ public MStabResults ExtractStabilityResults(string projectFileName)
+ {
+ ThrowHelper.ThrowIfStringArgumentNullOrEmpty(projectFileName, StringResourceNames.ProjectFileNameNullOrEmpty);
+ ThrowHelper.ThrowIfFileNotExist(projectFileName, StringResourceNames.ProjectFileNotExist);
+
+ try
+ {
+ if (ProgramType == ProgramType.SlopeW)
+ {
+ string outputFile = GetSlopeWOutputFileName(projectFileName);
+ return ParseSlopeWResultsFromOutputFile(outputFile);
+ }
+ else
+ {
+ string outputFile = Path.Combine(Path.GetDirectoryName(projectFileName), GetOutputFileName(projectFileName));
+ return ParseMStabResultsFromOutputFile(outputFile);
+ }
+ }
+ catch (ArgumentNullException argumentNullException)
+ {
+ string message = LocalizationManager.GetTranslatedText(this.GetType(), "CouldNotExtractSafetyFactor");
+ throw new StabilityServiceAgentException(message, argumentNullException);
+ }
+ catch (FileNotFoundException outputFileNotFoundException)
+ {
+ string message = LocalizationManager.GetTranslatedText(this.GetType(), "CouldNotExtractSafetyFactor");
+
+ string outputFile = Path.Combine(Path.GetDirectoryName(projectFileName), GetOutputFileName(projectFileName));
+ string[] errorMessages = ParseMStabErrorFile(outputFile);
+ if (errorMessages.Length > 0)
+ {
+ message = errorMessages[0];
+ }
+
+ throw new StabilityServiceAgentException(message, outputFileNotFoundException);
+ }
+ }
+
+ ///
+ /// Extract the beta-value from dumpfile of MStab
+ ///
+ ///
+ ///
+ public double ExtractBeta(string projectFileName)
+ {
+ ThrowHelper.ThrowIfStringArgumentNullOrEmpty(projectFileName, StringResourceNames.ProjectFileNameNullOrEmpty);
+ ThrowHelper.ThrowIfFileNotExist(projectFileName, StringResourceNames.ProjectFileNotExist);
+
+ string outputFile = Path.Combine(Path.GetDirectoryName(projectFileName), GetOutputFileName(projectFileName));
+
+ try
+ {
+ return ParseBetaFromOutputFile(outputFile);
+ }
+ catch (ArgumentNullException argumentNullException)
+ {
+ throw new StabilityServiceAgentException(argumentNullException.Message, argumentNullException);
+ }
+ catch (FileNotFoundException outputFileNotFoundException)
+ {
+ throw new StabilityServiceAgentException(outputFileNotFoundException.Message, outputFileNotFoundException);
+ }
+ }
+
+ #endregion
+
+ #region Helper Methods
+
+ private string CreateMStabIniFile(string inputFileName)
+ {
+ string filename = Path.GetTempFileName();
+ filename = Path.ChangeExtension(filename, "ini");
+ string defaultIniFilename = Path.Combine(Path.GetDirectoryName(MStabExePath), "DGeoStability.ini");
+ string newIniContent = "[D-Geo Stability batch processing]";
+ var isDirectoryBatchCalculation = Directory.Exists(inputFileName);
+ if (isDirectoryBatchCalculation)
+ {
+ newIniContent += System.Environment.NewLine + "Path=" + inputFileName;
+ newIniContent += System.Environment.NewLine + "Filespec=*.sti";
+ }
+ else
+ {
+ newIniContent += System.Environment.NewLine + "InputFileName=" + inputFileName;
+ }
+ newIniContent += System.Environment.NewLine + "Plot Critical Circle=1";
+ newIniContent += System.Environment.NewLine + "PlotWMF=1";
+ newIniContent += System.Environment.NewLine + "PlotJPeg=1";
+ if (File.Exists(defaultIniFilename))
+ {
+ string iniContent = File.ReadAllText(defaultIniFilename);
+ newIniContent += System.Environment.NewLine + System.Environment.NewLine + iniContent;
+ };
+ File.WriteAllText(filename, newIniContent);
+ return filename;
+
+ }
+
+ ///
+ /// Processes the input file using the working folder
+ ///
+ /// The folder or file name; for MStab: if a filename is specified then the file will be calculated; if a foldername is specified, all the stability files in the folder will be calculated. For SlopeW only filename is allowed
+ private void ProcessInputfFile(string folderOrFileName)
+ {
+ const string quote = "\"";
+ var argument = "";
+ var programpath = "";
+ string mStabIniFilename = "";
+ if (ProgramType == ProgramType.SlopeW)
+ {
+ programpath = SlopeWExePath;
+ argument = " /s /x " + quote + folderOrFileName + quote + " " + quote + Path.GetFileNameWithoutExtension(folderOrFileName) + quote;
+ }
+ else
+ {
+ programpath = MStabExePath;
+ mStabIniFilename = CreateMStabIniFile(folderOrFileName);
+ argument = string.Format("/b \"{0}\"", mStabIniFilename);
+
+ // For debugging and calling with commandline options i.s.o. inifile
+ //string filename = Path.GetTempFileName();
+ //File.WriteAllText(filename, programpath);
+ //File.WriteAllText(filename, argument);
+ //File.AppendAllText(filename, mStabIniFilename);
+ //argument = string.Format("/B /PlotJPeg /Plot \"{0}\"", folderOrFileName); // note: use the folder name only for running MStab in batch mode
+ //File.AppendAllText(filename, argument);
+ }
+
+ var process = new Process
+ {
+ StartInfo =
+ {
+ FileName = programpath,
+ Arguments = argument,
+ UseShellExecute = false
+ }
+
+ };
+
+ General.Parallel.KillOnAbort(process);
+
+ process.Start();
+
+ try
+ {
+ process.WaitForExit();
+ }
+ catch (ThreadInterruptedException)
+ {
+ // thread was killed by user action to stop calculation
+ }
+ finally
+ {
+ if (File.Exists(mStabIniFilename))
+ {
+ File.Delete(mStabIniFilename);
+ }
+ }
+ }
+
+
+ ///
+ /// Creates a random working folder by using a GUID
+ ///
+ /// The generated folder name
+ private static string CreateTempDirName()
+ {
+ return string.Format("{0}\\{1}", Path.GetTempPath(), Guid.NewGuid().ToString().Replace('-', '0'));
+ }
+
+ ///
+ /// Gets the stripped file name with the correct extension extracted from the input file name
+ ///
+ /// The file name with path
+ /// The project file name without path and correct extension
+ private static string GetOutputFileName(string projectFileName)
+ {
+ return GetStrippedFileNameWithoutExtension(projectFileName) + ".std";
+ }
+
+ ///
+ /// Gets the filename with the correct extension and the proper path for the outputfile for SlopeW
+ ///
+ /// The file name with path
+ /// The project file name with extended path and correct extension
+ private static string GetSlopeWOutputFileName(string projectFileName)
+ {
+ string outputFile = Path.GetDirectoryName(projectFileName);
+ outputFile = Path.Combine(outputFile, Path.GetFileNameWithoutExtension(projectFileName));
+ outputFile = Path.Combine(outputFile, "001");
+ outputFile = Path.Combine(outputFile, Path.GetFileNameWithoutExtension(projectFileName));
+ string outputFileTest = outputFile + ".optfrc";
+ if (!File.Exists(outputFileTest))
+ {
+ outputFileTest = outputFile + ".frc01";
+ }
+ if (!File.Exists(outputFileTest))
+ {
+ outputFileTest = "";
+ }
+ return outputFileTest;
+ }
+
+ ///
+ /// Gets the stripped file name without a path
+ ///
+ /// The file name
+ /// The project file name without path and correct extension
+ private static string GetInputFileName(string projectFileName)
+ {
+ return GetStrippedFileNameWithoutExtension(projectFileName) + ".sti";
+ }
+
+ ///
+ /// Gets the stripped file name without path and extension
+ ///
+ /// The file name to strip
+ /// The file name
+ private static string GetStrippedFileNameWithoutExtension(string fileName)
+ {
+ return fileName.Substring(fileName.LastIndexOf("\\") + 1).Split('.')[0];
+ }
+
+ ///
+ /// Gets the constructed file name with folder
+ ///
+ /// The name of the file
+ /// The name of the folder
+ /// The full file path
+ private static string GetFileName(string fileName, string folderName)
+ {
+ return string.Format("{0}\\{1}", folderName, fileName);
+ }
+
+ ///
+ /// Parses the safety factor from the output file
+ ///
+ /// The file to parse
+ /// The safety factor
+ private static MStabResults ParseMStabResultsFromOutputFile(string outputFile)
+ {
+ if (!File.Exists(outputFile))
+ throw new FileNotFoundException("No valid calculation performed");
+
+ var fileContent = StabilityServiceFileParser.GetFileContents(outputFile);
+ return StabilityServiceFileParser.GetMStabResults(fileContent);
+ }
+
+ ///
+ /// Parses the error messages from the error file
+ ///
+ /// The file to parse
+ /// The error messages
+ private string[] ParseMStabErrorFile(string outputFile)
+ {
+ string errorFile = outputFile.Replace(".std", ".err");
+
+ if (File.Exists(errorFile))
+ {
+ List messages = new List();
+ bool content = false;
+ foreach (string line in File.ReadAllLines(outputFile))
+ {
+ if (line.StartsWith("**********"))
+ {
+ content = !content;
+ }
+ else if (content)
+ {
+ messages.Add(line);
+ }
+ }
+
+ return messages.ToArray();
+ }
+ else
+ {
+ return new string[0];
+ }
+ }
+
+ ///
+ /// Parses the safety factor from the output file
+ ///
+ /// The file to parse
+ /// The safety factor
+ private static MStabResults ParseSlopeWResultsFromOutputFile(string outputFile)
+ {
+ if (!File.Exists(outputFile))
+ throw new FileNotFoundException("No valid calculation performed");
+
+ var fileContent = StabilityServiceFileParser.GetFileContents(outputFile);
+ return StabilityServiceFileParser.GetSlopeWResults(fileContent);
+ }
+
+ private static double ParseBetaFromOutputFile(string outputFile)
+ {
+ if (!File.Exists(outputFile))
+ throw new FileNotFoundException("No valid calculation performed");
+
+ var fileContent = StabilityServiceFileParser.GetFileContents(outputFile);
+ return StabilityServiceFileParser.GetBeta(fileContent);
+ }
+
+ #endregion
+
+ #region IDispose Members
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ // No need to call the finalizer since we've now cleaned
+ // up the unmanaged memory
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ // This finalizer is called when Garbage collection occurs, but only if
+ // the IDisposable.Dispose method wasn't already called.
+ ~StabilityServiceAgent()
+ {
+ Dispose(false);
+ }
+
+ #endregion
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/RWEvaluator.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/RWEvaluator.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/RWScenarios/RWEvaluator.cs (revision 334)
@@ -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 Deltares.DamEngine.Data.General;
+
+namespace Deltares.DamEngine.Data.RWScenarios
+{
+ public class RWEvaluator
+ {
+ protected Location location = null;
+ protected SoilGeometry soilGeometry = null;
+ private Enum[] previousChoices = null;
+
+ public RWEvaluator()
+ {
+ }
+
+ public virtual Enum Evaluate(Location location, SoilGeometry soilGeometry, params Enum[] previousChoices)
+ {
+ this.location = location;
+ this.soilGeometry = soilGeometry;
+ this.previousChoices = previousChoices;
+
+ return null;
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryConstants.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryConstants.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryConstants.cs (revision 334)
@@ -0,0 +1,69 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Class holding all geometry related constants
+ ///
+ public static class GeometryConstants
+ {
+ ///
+ /// The default left limit of the geometry
+ ///
+ public const double DefaultLeftLimitGeometry = 0.0;
+
+ ///
+ /// The default right limit of the geometry
+ ///
+ public const double DefaultRightLimitGeometry = 50.0;
+
+ ///
+ /// The default bottom limit of the geometry
+ ///
+ public const double DefaultBottomLimitGeometry = -10.0;
+
+ ///
+ /// The accuracy as used for the geometry objects
+ ///
+ public const double Accuracy = 0.001;
+
+ ///
+ /// The volumic weight of water
+ ///
+ public const double VolumicWeightOfWater = 9.81;
+ }
+
+ ///
+ /// Pointtype as used by intersection methods and other helper methods to determine for which plane the method has to work.
+ ///
+// public enum PointType
+// {
+// ///
+// /// The xy plane
+// ///
+// XY,
+// ///
+// /// The xz plane
+// ///
+// XZ
+// }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilLayer.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilLayer.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilLayer.cs (revision 334)
@@ -0,0 +1,74 @@
+// 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 Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Standard.Language;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Soil Layer object
+ ///
+ public class SoilLayer : GeometryObject
+ {
+ ///
+ /// Gets or sets the soil object
+ ///
+ /// soil value
+ public virtual Soil Soil { get; set; }
+
+ ///
+ /// Defines whether the layer acts as aquifer (true) or aquitard (false).
+ ///
+ public virtual bool IsAquifer { get; set; }
+
+
+
+ ///
+ /// Gets or sets the waterpressure interpolation model.
+ ///
+ ///
+ /// The waterpressure interpolation model.
+ ///
+ public virtual WaterpressureInterpolationModel WaterpressureInterpolationModel { get; set; }
+
+
+ ///
+ /// Validates the layer.
+ ///
+ ///
+ [Validate]
+ public ValidationResult[] ValidateLayer()
+ {
+ var results = new List();
+ {
+ if (Soil == null)
+ {
+ results.Add(new ValidationResult(ValidationResultType.Error, LocalizationManager.GetTranslatedText(GetType(), "NoSoilAssigned"), this));
+ }
+ }
+ return results.ToArray();
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointSet.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointSet.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointSet.cs (revision 334)
@@ -0,0 +1,571 @@
+// 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.Linq;
+using Deltares.DamEngine.Data.Geometry;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Represents a meta-data set of instances that describe
+ /// special point-locations of a geometric surfaceline.
+ ///
+ public class CharacteristicPointSet : IList, IList
+ {
+ private readonly List annotations;
+ private readonly object syncRoot = new object();
+ private readonly Dictionary typeCache;
+ private GeometryPointString geometry;
+ private bool geometryMustContainPoint;
+
+ ///
+ /// Creates a characteristic point set whose points act as meta data for a geometric
+ /// description ( false) of a surfaceline.
+ ///
+ public CharacteristicPointSet()
+ {
+ typeCache = new Dictionary();
+ annotations = new List();
+ geometryMustContainPoint = false;
+ }
+
+ ///
+ /// The observed localized geometry point string, describing the dike surfaceline
+ /// shape.
+ ///
+ /// References by aggregation.
+ public GeometryPointString Geometry
+ {
+ get
+ {
+ return geometry;
+ }
+ set
+ {
+ geometry = value;
+
+ FullSyncWithGeometry();
+ }
+ }
+
+ ///
+ /// When true, requires all instances part of
+ /// this set to be contained in and cannot have instances
+ /// not part of .
+ /// When false, all instances are required NOT
+ /// to be part of . Their height will then be determined by
+ /// the height profile defined by .
+ ///
+ public bool GeometryMustContainPoint
+ {
+ get
+ {
+ return geometryMustContainPoint;
+ }
+ set
+ {
+ geometryMustContainPoint = value;
+
+ FullSyncWithGeometry();
+ }
+ }
+
+ ///
+ /// Retrieves the annotated with the given type.
+ ///
+ /// Annotation to look for.
+ /// The instances annotated with the given type;
+ /// Null if no definition can be found.
+ /// This method relies on this class observing changes to its
+ /// to work correctly.
+ public GeometryPoint GetGeometryPoint(CharacteristicPointType characteristicPointType)
+ {
+ return typeCache.ContainsKey(characteristicPointType)
+ ? typeCache[characteristicPointType]
+ : null;
+ }
+
+ ///
+ /// Sorts this characteristic point set items on
+ /// ascending. If is true,
+ /// shall also be sorted.
+ ///
+ public void Sort()
+ {
+ if (GeometryMustContainPoint && Geometry != null)
+ {
+ Geometry.SortPointsByXAscending();
+ }
+ annotations.Sort();
+ }
+
+ ///
+ /// Annotates the characteristic point at the specified index.
+ ///
+ /// The index.
+ /// The new type of the characteristic point.
+ /// When is
+ /// less then 0 or greater or equal to .
+ /// will be returning the correct points.
+ public void Annotate(int index, CharacteristicPointType characteristicPointType)
+ {
+ annotations[index].CharacteristicPointType = characteristicPointType;
+ UpdateTypeCache(annotations[index]);
+ }
+
+ #region Implementation: IList, IList
+
+ ///
+ /// Gets an object that can be used to synchronize access to the .
+ ///
+ public object SyncRoot
+ {
+ get
+ {
+ return syncRoot;
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether access to the is synchronized (thread safe).
+ ///
+ public bool IsSynchronized
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether the has a fixed size.
+ ///
+ public bool IsFixedSize
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Gets or sets the element at the specified index.
+ ///
+ /// The index.
+ ///
+ object IList.this[int index]
+ {
+ get
+ {
+ return this[index];
+ }
+ set
+ {
+ this[index] = (CharacteristicPoint) value;
+ }
+ }
+
+ ///
+ /// Gets the number of elements contained in the .
+ ///
+ public int Count
+ {
+ get
+ {
+ return annotations.Count;
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether the is read-only.
+ ///
+ public bool IsReadOnly
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Gets or sets the element at the specified index.
+ ///
+ /// The index.
+ ///
+ public CharacteristicPoint this[int index]
+ {
+ get
+ {
+ return annotations[index];
+ }
+ set
+ {
+ RemoveAt(index);
+ Insert(index, value);
+ }
+ }
+
+ ///
+ /// Adds an item to the .
+ ///
+ /// The object to add to the .
+ ///
+ /// The position into which the new element was inserted, or -1 to indicate that the item was not inserted into the collection,
+ ///
+ public int Add(object value)
+ {
+ Add((CharacteristicPoint) value);
+ return Count - 1;
+ }
+
+ ///
+ /// Determines whether the contains a specific value.
+ ///
+ /// The object to locate in the .
+ ///
+ /// true if the is found in the ; otherwise, false.
+ ///
+ public bool Contains(object value)
+ {
+ var cp = value as CharacteristicPoint;
+ if (cp == null)
+ {
+ return false;
+ }
+
+ return Contains(cp);
+ }
+
+ ///
+ /// Copies the elements of the to an , starting at a particular index.
+ ///
+ /// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing.
+ /// The zero-based index in at which copying begins.
+ public void CopyTo(Array array, int index)
+ {
+ CopyTo((CharacteristicPoint[]) array, index);
+ }
+
+ ///
+ /// Determines the index of a specific item in the .
+ ///
+ /// The object to locate in the .
+ ///
+ /// The index of if found in the list; otherwise, -1.
+ ///
+ public int IndexOf(object value)
+ {
+ return IndexOf((CharacteristicPoint) value);
+ }
+
+ ///
+ /// Inserts an item to the at the specified index.
+ ///
+ /// The zero-based index at which should be inserted.
+ /// The object to insert into the .
+ public void Insert(int index, object value)
+ {
+ Insert(index, (CharacteristicPoint) value);
+ }
+
+ ///
+ /// Removes the first occurrence of a specific object from the .
+ ///
+ /// The object to remove from the .
+ public void Remove(object value)
+ {
+ Remove((CharacteristicPoint) value);
+ }
+
+ ///
+ /// Removes the first occurrence of a specific object from the .
+ ///
+ /// The object to remove from the .
+ ///
+ /// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original .
+ ///
+ public bool Remove(CharacteristicPoint item)
+ {
+ var removed = PerformCollectionRemoveWithEvents(annotations, item);
+
+ if (removed)
+ {
+ typeCache.Remove(item.CharacteristicPointType);
+
+ var removeGeometryPoint = GeometryMustContainPoint && Geometry != null &&
+ Geometry.Points.Contains(item.GeometryPoint) &&
+ !annotations.Any(cp => ReferenceEquals(cp.GeometryPoint, item.GeometryPoint));
+
+ if (removeGeometryPoint)
+ {
+ PerformCollectionRemoveWithEvents(Geometry.Points, item.GeometryPoint);
+ }
+ }
+
+ return removed;
+ }
+
+ ///
+ /// Adds an item to the .
+ ///
+ /// The object to add to the .
+ public void Add(CharacteristicPoint item)
+ {
+ Insert(Count, item);
+ }
+
+ ///
+ /// Removes all items from the .
+ ///
+ public void Clear()
+ {
+ ClearCharacteristicPointSet();
+
+ if (GeometryMustContainPoint && Geometry != null)
+ {
+ Geometry.Points.Clear();
+ Geometry.CalcPoints.Clear();
+ }
+ }
+
+ ///
+ /// Determines whether the contains a specific value.
+ ///
+ /// The object to locate in the .
+ ///
+ /// true if is found in the ; otherwise, false.
+ ///
+ public bool Contains(CharacteristicPoint item)
+ {
+ return annotations.Contains(item);
+ }
+
+ ///
+ /// Copies to.
+ ///
+ /// The array.
+ /// Index of the array.
+ public void CopyTo(CharacteristicPoint[] array, int arrayIndex)
+ {
+ annotations.CopyTo(array, arrayIndex);
+ }
+
+ ///
+ /// Determines the index of a specific item in the .
+ ///
+ /// The object to locate in the .
+ ///
+ /// The index of if found in the list; otherwise, -1.
+ ///
+ public int IndexOf(CharacteristicPoint item)
+ {
+ return annotations.IndexOf(item);
+ }
+
+ ///
+ /// Inserts an item to the at the specified index.
+ ///
+ /// The zero-based index at which should be inserted.
+ /// The object to insert into the .
+ public void Insert(int index, CharacteristicPoint item)
+ {
+ if (!ReferenceEquals(item.PointSet, this))
+ {
+ item.PointSet = this;
+ }
+ var itemAtIndex = index < annotations.Count ? annotations[index].GeometryPoint : null;
+ PerformListInsertWithEvents(annotations, item, index);
+ if (GeometryMustContainPoint && Geometry != null && !Geometry.Points.Contains(item.GeometryPoint))
+ {
+ var geometryIndex = Geometry.Points.Count;
+ if (null != itemAtIndex)
+ {
+ for (int i = 0; i < Geometry.Points.Count; i++)
+ {
+ if (ReferenceEquals(Geometry.Points[i], itemAtIndex))
+ {
+ geometryIndex = i;
+ break;
+ }
+ }
+ }
+ PerformListInsertWithEvents(Geometry.Points, item.GeometryPoint, geometryIndex);
+ }
+
+ UpdateCharacteristicPointHeight(item);
+ UpdateTypeCache(item);
+ }
+
+ ///
+ /// Removes the item at the specified index.
+ ///
+ /// The zero-based index of the item to remove.
+ public void RemoveAt(int index)
+ {
+ Remove(annotations[index]);
+ }
+
+ ///
+ /// Returns an enumerator that iterates through a collection.
+ ///
+ ///
+ /// An object that can be used to iterate through the collection.
+ ///
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ ///
+ /// Returns an enumerator that iterates through the collection.
+ ///
+ ///
+ /// A that can be used to iterate through the collection.
+ ///
+ public IEnumerator GetEnumerator()
+ {
+ return annotations.GetEnumerator();
+ }
+
+ #endregion
+
+ #region Events
+
+ ///
+ ///
+ /// Type of the list elements.
+ /// The list where the item is inserted into.
+ /// The item inserted into the list.
+ /// Index where the item is inserted.
+ private static void PerformListInsertWithEvents(IList list, T item, int index)
+ {
+ list.Insert(index, item);
+ }
+
+ private static bool PerformCollectionRemoveWithEvents(ICollection list, T item)
+ {
+ var removed = list.Remove(item);
+
+ return removed;
+ }
+
+ #endregion
+
+ ///
+ /// Snaps the characteristic point height to if it's not part
+ /// of it, or set it to in case no
+ /// is available.
+ ///
+ /// The characteristic point whose height is to be updated.
+ private void UpdateCharacteristicPointHeight(CharacteristicPoint characteristicPoint)
+ {
+ if (geometry == null)
+ {
+ characteristicPoint.Z = double.NaN;
+ }
+ else if (!geometry.Points.Contains(characteristicPoint.GeometryPoint))
+ {
+ if (double.IsNaN(characteristicPoint.X))
+ {
+ characteristicPoint.Z = double.NaN;
+ }
+ else
+ {
+ // Note: Cannot use GeometryPointString.GetZAtX due to its requirement
+ // that Geometry.Points is sorted on X.
+ characteristicPoint.Z = geometry.GetZAtUnsortedX(characteristicPoint.X);
+ }
+ }
+ // Else: Keep Z the same as in Geometry
+ }
+
+ private void FullSyncWithGeometry()
+ {
+ if (GeometryMustContainPoint)
+ {
+ // Resync with geometry; Do not keep previous data:
+ ClearCharacteristicPointSet();
+
+ if (geometry == null)
+ {
+ return;
+ }
+
+ foreach (var geometryPoint in geometry.Points)
+ {
+ Add(new CharacteristicPoint
+ {
+ GeometryPoint = geometryPoint,
+ CharacteristicPointType = CharacteristicPointType.None
+ });
+ }
+ }
+ else
+ {
+ // Remove all characteristic points whose GeometryPoint are part of Geometry
+ // as per required by the value of GeometryMustContainPoint. All other
+ // characteristic points should have their height updated:
+ foreach (var characteristicPoint in annotations.ToArray())
+ {
+ if (geometry != null && geometry.Points.Contains(characteristicPoint.GeometryPoint))
+ {
+ Remove(characteristicPoint);
+ }
+ else
+ {
+ UpdateCharacteristicPointHeight(characteristicPoint);
+ }
+ }
+ }
+ }
+
+ private void ClearCharacteristicPointSet()
+ {
+ ClearAnnotations();
+ typeCache.Clear();
+ }
+
+ private void ClearAnnotations()
+ {
+ annotations.Clear();
+ }
+
+ private void UpdateTypeCache(CharacteristicPoint item)
+ {
+ if (item.CharacteristicPointType != CharacteristicPointType.None)
+ {
+ // Prevent duplication:
+ var alreadyDefined = annotations.FirstOrDefault(cp => cp.CharacteristicPointType == item.CharacteristicPointType &&
+ !ReferenceEquals(cp.GeometryPoint, item.GeometryPoint));
+ if (alreadyDefined != null)
+ {
+ alreadyDefined.CharacteristicPointType = CharacteristicPointType.None;
+ }
+
+ // Set new annotation definition:
+ typeCache[item.CharacteristicPointType] = item.GeometryPoint;
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/CoordinateSystemConverter.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/CoordinateSystemConverter.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/CoordinateSystemConverter.cs (revision 334)
@@ -0,0 +1,295 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Exception class for .
+ ///
+ public class CoordinateSystemConverterException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The message that describes the error.
+ public CoordinateSystemConverterException(string message)
+ : base(message) {}
+ }
+
+ ///
+ /// class for converting object coordinates from global to local system and back.
+ ///
+ /// Converter assumes all points of the given line are in the same vertical
+ /// 2D plane.
+ public class CoordinateSystemConverter
+ {
+ private double cosAlpha = 0;
+ private double endX;
+ private double endY;
+ private bool isGlobalXYZDefined = false;
+
+ private double length;
+ private double sinAlpha = 0;
+ private double startX = 0.0;
+ private double startY = 0.0;
+
+ ///
+ /// cos(alpha) of x-axis of local XYZ system
+ ///
+ public double CosAlpha
+ {
+ get
+ {
+ ThrowIfGlobalXYZNotDefined();
+ return cosAlpha;
+ }
+ }
+
+ ///
+ /// sin(alpha) of x-axis of local XYZ system
+ ///
+ public double SinAlpha
+ {
+ get
+ {
+ ThrowIfGlobalXYZNotDefined();
+ return sinAlpha;
+ }
+ }
+
+ ///
+ /// x-coordinate of origin of local XYZ system
+ ///
+ public double XStart
+ {
+ get
+ {
+ ThrowIfGlobalXYZNotDefined();
+ return startX;
+ }
+ }
+
+ ///
+ /// y-coordinate of origin start point of local XYZ system
+ ///
+ public double YStart
+ {
+ get
+ {
+ ThrowIfGlobalXYZNotDefined();
+ return startY;
+ }
+ }
+
+ ///
+ /// x-coordinate of origin last point
+ ///
+ public double XEnd
+ {
+ get
+ {
+ ThrowIfGlobalXYZNotDefined();
+ return endX;
+ }
+ }
+
+ ///
+ /// y-coordinate of origin end point
+ ///
+ public double YEnd
+ {
+ get
+ {
+ ThrowIfGlobalXYZNotDefined();
+ return endY;
+ }
+ }
+
+ ///
+ /// Gets the length.
+ ///
+ ///
+ /// The length.
+ ///
+ public double Length
+ {
+ get
+ {
+ ThrowIfGlobalXYZNotDefined();
+ return length;
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether [converted to local].
+ ///
+ ///
+ /// true if [converted to local]; otherwise, false.
+ ///
+ public bool ConvertedToLocal { get; private set; }
+
+ ///
+ /// Define parameters to parameterize the global reference system.
+ ///
+ /// Line defined in global coordinates.
+ public void DefineGlobalXYZBasedOnLine(GeometryPointString globalLine)
+ {
+ GeometryPoint firstPoint = globalLine.Points[0];
+ GeometryPoint lastPoint = globalLine.Points[globalLine.Points.Count - 1];
+
+ double dX = lastPoint.X - firstPoint.X;
+ double dY = lastPoint.Y - firstPoint.Y;
+
+ length = Math.Sqrt(dX*dX + dY*dY);
+
+ cosAlpha = dX/length;
+ sinAlpha = dY/length;
+
+ startX = firstPoint.X;
+ startY = firstPoint.Y;
+
+ endX = lastPoint.X;
+ endY = lastPoint.Y;
+
+ isGlobalXYZDefined = true;
+ }
+
+ ///
+ /// Define parameters to define global reference system
+ ///
+ [Obsolete]
+ public void DefineLocalXZBasedOnSavedProperties(double originalX, double originalY, double angle)
+ {
+ cosAlpha = Math.Cos(angle);
+ sinAlpha = Math.Sin(angle);
+ startX = originalX;
+ startY = originalY;
+ isGlobalXYZDefined = true;
+ }
+
+ ///
+ /// Projects a global coordinate to a local XZ reference system.
+ ///
+ /// Global coordinate.
+ ///
+ /// When global parameters haven't
+ /// been defined yet with .
+ public void ConvertGlobalXYZToLocalXZ(GeometryPoint globalPoint)
+ {
+ ThrowIfGlobalXYZNotDefined();
+
+ globalPoint.X = GetLocalXForGlobalPoint(globalPoint);
+ globalPoint.Y = 0.0;
+ }
+
+ ///
+ /// Projects a line of global coordinates to a local XZ reference system.
+ ///
+ /// Th line in global coordinates.
+ ///
+ public void ConvertGlobalXYZToLocalXZ(GeometryPointString globalLine)
+ {
+ if (!isGlobalXYZDefined)
+ {
+ DefineGlobalXYZBasedOnLine(globalLine);
+ }
+ ThrowIfGlobalXYZNotDefined();
+
+ foreach (var point in globalLine.Points)
+ {
+ ConvertGlobalXYZToLocalXZ(point);
+ }
+ ConvertedToLocal = true;
+ }
+
+ ///
+ /// Projects a local coordinate back to the parameterized global XYZ reference system.
+ ///
+ /// Local coordinate.
+ ///
+ /// When global parameters haven't
+ /// been defined yet with .
+ public void ConvertLocalXZToGlobalXYZ(GeometryPoint localPoint)
+ {
+ ThrowIfGlobalXYZNotDefined();
+
+ double localX = localPoint.X*cosAlpha + startX;
+ double localY = localPoint.X*sinAlpha + startY;
+ localPoint.X = localX;
+ localPoint.Y = localY;
+ }
+
+ ///
+ /// Projects a XZ-line local coordinates back to the parameterized global XYZ reference system.
+ ///
+ /// Line in local coordinates.
+ ///
+ /// When global parameters haven't
+ /// been defined yet with .
+ public void ConvertLocalXZToGlobalXYZ(GeometryPointString localLine)
+ {
+ ThrowIfGlobalXYZNotDefined();
+
+ foreach (var point in localLine.Points)
+ {
+ ConvertLocalXZToGlobalXYZ(point);
+ }
+ }
+
+ private double GetLocalXForGlobalPoint(GeometryPoint globalPoint)
+ {
+ const double cSinCosThreshold = 0.4;
+
+ double dX = globalPoint.X - startX;
+ double dY = globalPoint.Y - startY;
+
+ double localXfromGlobalX = dX/cosAlpha;
+ if (Math.Abs(sinAlpha) < cSinCosThreshold)
+ {
+ // if line tends to be horizontal use local x calculated based on dX
+ return localXfromGlobalX;
+ }
+
+ double localXfromGlobalY = dY/sinAlpha;
+ if (Math.Abs(cosAlpha) < cSinCosThreshold)
+ {
+ // if line tends to be vertical use local x calculated based on dY
+ return localXfromGlobalY;
+ }
+
+ // if angle around 45 degrees then use the mean between the 2 values
+ return (localXfromGlobalX + localXfromGlobalY)/2;
+ }
+
+ ///
+ /// Raise exception if Global XYZ reference system is not defined
+ ///
+ private void ThrowIfGlobalXYZNotDefined()
+ {
+ if (!isGlobalXYZDefined)
+ {
+ throw new CoordinateSystemConverterException("Global reference coordinate system is not defined");
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/DamEngine.sln
===================================================================
diff -u -r304 -r334
--- dam engine/trunk/src/DamEngine.sln (.../DamEngine.sln) (revision 304)
+++ dam engine/trunk/src/DamEngine.sln (.../DamEngine.sln) (revision 334)
@@ -7,6 +7,10 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deltares.DamEngine.Interface.Tests", "Deltares.DamEngine.Interface.Tests\Deltares.DamEngine.Interface.Tests.csproj", "{968516F9-1B92-4ADB-AE4A-CFF54EE43126}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deltares.DamEngine.Calculators", "Deltares.DamEngine.Calculators\Deltares.DamEngine.Calculators.csproj", "{E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deltares.DamEngine.Data", "Deltares.DamEngine.Data\Deltares.DamEngine.Data.csproj", "{B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
@@ -21,6 +25,14 @@
{968516F9-1B92-4ADB-AE4A-CFF54EE43126}.Debug|x86.Build.0 = Debug|x86
{968516F9-1B92-4ADB-AE4A-CFF54EE43126}.Release|x86.ActiveCfg = Release|x86
{968516F9-1B92-4ADB-AE4A-CFF54EE43126}.Release|x86.Build.0 = Release|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Debug|x86.ActiveCfg = Debug|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Debug|x86.Build.0 = Debug|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Release|x86.ActiveCfg = Release|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Release|x86.Build.0 = Release|x86
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Debug|x86.ActiveCfg = Debug|x86
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Debug|x86.Build.0 = Debug|x86
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Release|x86.ActiveCfg = Release|x86
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/Point2D.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/Point2D.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/Point2D.cs (revision 334)
@@ -0,0 +1,111 @@
+// 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.ComponentModel;
+using Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Class for pure X,Z coors, to be used in calculation
+ ///
+ [TypeConverter(typeof(ExpandableObjectConverter))]
+ public class Point2D : IComparable
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Point2D()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The x.
+ /// The z.
+ public Point2D(double x, double z)
+ {
+ X = x;
+ Z = z;
+ }
+
+ ///
+ /// The x
+ ///
+ public double X;
+
+ ///
+ /// The z
+ ///
+ public double Z;
+
+ ///
+ /// Determines whether the location of the given point and this one are the same.
+ ///
+ /// The other.
+ ///
+ public bool LocationEquals(Point2D other)
+ {
+ return LocationEquals(other, GeometryConstants.Accuracy);
+ }
+
+ ///
+ /// Determines whether the difference between the location of the given point and
+ /// this one are within the given precision.
+ ///
+ /// The other.
+ /// The precision.
+ ///
+ public bool LocationEquals(Point2D other, double precision)
+ {
+ if (ReferenceEquals(other, null))
+ {
+ return false;
+ }
+ if (ReferenceEquals(other, this))
+ {
+ return true;
+ }
+
+ return X.AlmostEquals(other.X, precision) &&
+ Z.AlmostEquals(other.Z, precision);
+ }
+
+ ///
+ /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
+ ///
+ /// An object to compare with this instance.
+ ///
+ /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes in the sort order. Zero This instance occurs in the same position in the sort order as . Greater than zero This instance follows in the sort order.
+ ///
+ public int CompareTo(object obj)
+ {
+ var point = obj as Point2D;
+ if (point != null)
+ {
+ return X.CompareTo(point.X);
+ }
+ return String.Compare(ToString(), obj.ToString(), StringComparison.Ordinal);
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs (revision 334)
@@ -0,0 +1,546 @@
+// 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.Geometry;
+using Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// All extension-methods for .
+ ///
+ public static class SurfaceLine2Extensions
+ {
+ ///
+ /// Returns all that require to be sorted on X
+ /// ascending.
+ ///
+ /// The evaluated surfaceline.
+ /// Collection of characteristic points, ordered by type from the point
+ /// expecting the lowest X coordinate in the set through to the one expecting the
+ /// highest X coordinate.
+ public static IEnumerable GetCharacteristicPointsRequiringAscendingX(this SurfaceLine2 line)
+ {
+ return line.CharacteristicPoints.Where(p =>
+ !double.IsNaN(p.X) && // Note: This probably shall no longer apply to SurfaceLine2
+ p.CharacteristicPointType != CharacteristicPointType.None &&
+ p.CharacteristicPointType != CharacteristicPointType.TrafficLoadInside &&
+ p.CharacteristicPointType != CharacteristicPointType.TrafficLoadOutside).
+ OrderBy(p => p.CharacteristicPointType);
+ }
+
+ ///
+ /// Checks whether the specified line has the given annotation.
+ ///
+ /// The surface line to be checked.
+ /// The type.
+ ///
+ ///
+ public static bool HasAnnotation(this SurfaceLine2 line, CharacteristicPointType type)
+ {
+ return line.CharacteristicPoints.GetGeometryPoint(type) != null;
+ }
+
+ ///
+ /// Determines whether the specified characteristic point type is defined (has
+ /// the given annotation and its X coordinate is not ).
+ ///
+ /// The evaluated surfaceline.
+ /// Type of the characteristic point.
+ /// true if input parameter is defined
+ ///
+ public static bool IsDefined(this SurfaceLine2 line, CharacteristicPointType characteristicPointType)
+ {
+ // TODO: GRASP: Information Expert -> CharacteristicPoint class should be responsible for this logic.
+ return line.HasAnnotation(characteristicPointType) &&
+ !Double.IsNaN(line.CharacteristicPoints.GetGeometryPoint(characteristicPointType).X);
+ }
+
+ ///
+ /// Gets the absolute height ([m]) of the dike.
+ ///
+ /// Height of dike, or null if
+ /// is not defined for the surface line.
+ public static double? GetDikeHeight(this SurfaceLine2 line)
+ {
+ var dikeTopAtRiver = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver);
+ if (dikeTopAtRiver != null)
+ {
+ return dikeTopAtRiver.Z;
+ }
+ return null;
+ }
+
+ ///
+ /// If shoulder is present then the toe of the shoulder ()
+ /// is returned, else the toe of the dike ()
+ /// is returned.
+ ///
+ /// Toe of the dike, or null if none of the required characteristic
+ /// annotations can be found.
+ public static GeometryPoint GetDikeToeInward(this SurfaceLine2 line)
+ {
+ return line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside) ??
+ line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder);
+ }
+
+ ///
+ /// Gets the length of the dike.
+ ///
+ /// dike length or null in case toe points are null
+ public static double? GetDikeLength(this SurfaceLine2 line)
+ {
+ var dikeToeAtRiver = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver);
+ var dikeToeAtPolder = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder);
+
+ if (dikeToeAtRiver != null && dikeToeAtPolder != null)
+ {
+ return Math.Abs(dikeToeAtRiver.X - dikeToeAtPolder.X);
+ }
+ return null;
+ }
+
+ ///
+ /// Checks if a surfaceline has all characteristic point types required to describe
+ /// a dike.
+ ///
+ /// Surfaceline to be checked.
+ /// True if there are characteristic points defined that describe a dike;
+ /// False otherwise.
+ public static bool HasDike(this SurfaceLine2 line)
+ {
+ return IsDefined(line, CharacteristicPointType.DikeToeAtRiver) &&
+ IsDefined(line, CharacteristicPointType.DikeTopAtRiver) &&
+ 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/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilList.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilList.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilList.cs (revision 334)
@@ -0,0 +1,138 @@
+// 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.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Holds the soils and provides some handy methods for them
+ ///
+ public class SoilList
+ {
+ private Dictionary aquiferDictionary = new Dictionary();
+ private List soils;
+
+ public SoilList()
+ {
+ soils = new List();
+ }
+
+ ///
+ /// Gets or sets the soils.
+ ///
+ ///
+ /// The soils.
+ ///
+ [Validate]
+ public virtual List Soils
+ {
+ get
+ {
+ return soils;
+ }
+ set
+ {
+ soils = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the aquifer dictionary.
+ /// This dictionary is used for the backward compatibility issue when aquifers still were part of
+ /// soil instead of the layer as it is now.
+ ///
+ ///
+ /// The aquifer dictionary.
+ ///
+ public Dictionary AquiferDictionary
+ {
+ get
+ {
+ return aquiferDictionary;
+ }
+ set
+ {
+ aquiferDictionary = value;
+ }
+ }
+
+ ///
+ /// Gets the index of the soil by its name.
+ ///
+ /// Name of the soil.
+ /// The index when found else -1
+ public virtual int GetSoilIndexByName(string soilName)
+ {
+ var soil = soils.FirstOrDefault(s => s.Name.Equals(
+ soilName, StringComparison.InvariantCultureIgnoreCase));
+
+ return soil == null ? -1 : soils.IndexOf(soil);
+ }
+
+ ///
+ /// Gets the soil by its name.
+ ///
+ /// Name of the soil.
+ /// Soil when found else null
+ public virtual Soil GetSoilByName(string soilName)
+ {
+ var soil = soils.FirstOrDefault(s => s.Name.Equals(
+ soilName, StringComparison.InvariantCultureIgnoreCase));
+
+ return soil;
+ }
+
+ ///
+ /// Adds the specified soil.
+ ///
+ /// The soil.
+ public void Add(Soil soil)
+ {
+ Soils.Add(soil);
+ }
+
+ ///
+ /// Removes the specified soil.
+ ///
+ /// The soil.
+ public void Remove(Soil soil)
+ {
+ Soils.Remove(soil);
+ if (aquiferDictionary.ContainsKey(soil))
+ {
+ aquiferDictionary.Remove(soil);
+ }
+ }
+
+ ///
+ /// Clears this instance (soils and AquiferDictionary).
+ ///
+ public void Clear()
+ {
+ Soils.Clear();
+ aquiferDictionary.Clear();
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/MStabParameters.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/MStabParameters.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/MStabParameters.cs (revision 334)
@@ -0,0 +1,621 @@
+// 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.ComponentModel;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.Standard;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public enum TangentLinesDefinition
+ {
+ OnBoundaryLines = 0,
+ Specified = 1
+ }
+
+ public enum GridSizeDetermination
+ {
+ Automatic = 0,
+ Specified = 1
+ }
+
+ public class SheetPiling : IAssignable, ICloneable
+ {
+ public double XCoordinate { get; set; }
+ public double YCoordinate { get; set; }
+ public double ZCoordinate { get; set; }
+ public double Length { get; set; }
+
+ public void Assign(SheetPiling sheetPiling)
+ {
+ this.XCoordinate = sheetPiling.XCoordinate;
+ this.YCoordinate = sheetPiling.YCoordinate;
+ this.ZCoordinate = sheetPiling.ZCoordinate;
+ this.Length = sheetPiling.Length;
+ }
+
+ public SheetPiling Clone()
+ {
+ var sheetPiling = new SheetPiling();
+ sheetPiling.Assign(this);
+ return sheetPiling;
+ }
+ }
+
+ public class HorizontalBalanceArea : IAssignable, ICloneable
+ {
+ public double XLeft { get; set; }
+ public double XRight { get; set; }
+ public double YTop { get; set; }
+ public double YBottom { get; set; }
+ public int PlaneCount { get; set; }
+ public void Assign(HorizontalBalanceArea horizontalBalanceArea)
+ {
+ this.XLeft = horizontalBalanceArea.XLeft;
+ this.XRight = horizontalBalanceArea.XRight;
+ this.YTop = horizontalBalanceArea.YTop;
+ this.YBottom = horizontalBalanceArea.YBottom;
+ this.PlaneCount = horizontalBalanceArea.PlaneCount;
+ }
+
+ public HorizontalBalanceArea Clone()
+ {
+ var horizontalBalanceArea = new HorizontalBalanceArea();
+ horizontalBalanceArea.Assign(this);
+ return horizontalBalanceArea;
+ }
+ }
+
+ public class SlipCircleDefinition : IAssignable, ICloneable
+ {
+ private double xCoordinateLastUpliftPoint;
+ private int upliftVanLeftGridVerticalPointCount;
+ private double upliftVanTangentLinesDistance;
+ private double bishopTangentLinesDistance;
+ private double upliftVanLeftGridVerticalPointDistance;
+ private int upliftVanLeftGridHorizontalPointCount;
+ private double upliftVanLeftGridHorizontalPointDistance;
+ private int upliftVanRightGridVerticalPointCount;
+ private double upliftVanRightGridVerticalPointDistance;
+ private int upliftVanRightGridHorizontalPointCount;
+ private double upliftVanRightGridHorizontalPointDistance;
+ private int bishopGridHorizontalPointCount;
+ private double bishopGridHorizontalPointDistance;
+ private int bishopGridVerticalPointCount;
+ private double bishopGridVerticalPointDistance;
+
+ public double XCoordinateLastUpliftPoint
+ {
+ get
+ {
+ return xCoordinateLastUpliftPoint;
+ }
+ set
+ {
+ xCoordinateLastUpliftPoint = value;
+ }
+ }
+ public TangentLinesDefinition UpliftVanTangentLinesDefinition { get; set; }
+
+ public double UpliftVanTangentLinesDistance
+ {
+ get
+ {
+ return upliftVanTangentLinesDistance;
+ }
+ set
+ {
+ upliftVanTangentLinesDistance = value;
+ }
+ }
+ public TangentLinesDefinition BishopTangentLinesDefinition { get; set; }
+
+ public double BishopTangentLinesDistance
+ {
+ get
+ {
+ return bishopTangentLinesDistance;
+ }
+ set
+ {
+ bishopTangentLinesDistance = value;
+ }
+ }
+ public GridSizeDetermination GridSizeDetermination { get; set; }
+
+ public int UpliftVanLeftGridVerticalPointCount
+ {
+ get
+ {
+ return upliftVanLeftGridVerticalPointCount;
+ }
+ set
+ {
+ upliftVanLeftGridVerticalPointCount = value;
+ }
+ }
+
+ public double UpliftVanLeftGridVerticalPointDistance
+ {
+ get
+ {
+ return upliftVanLeftGridVerticalPointDistance;
+ }
+ set
+ {
+ upliftVanLeftGridVerticalPointDistance = value;
+ }
+ }
+
+ public int UpliftVanLeftGridHorizontalPointCount
+ {
+ get
+ {
+ return upliftVanLeftGridHorizontalPointCount;
+ }
+ set
+ {
+ upliftVanLeftGridHorizontalPointCount = value;
+ }
+ }
+
+ public double UpliftVanLeftGridHorizontalPointDistance
+ {
+ get
+ {
+ return upliftVanLeftGridHorizontalPointDistance;
+ }
+ set
+ {
+ upliftVanLeftGridHorizontalPointDistance = value;
+ }
+ }
+
+ public int UpliftVanRightGridVerticalPointCount
+ {
+ get
+ {
+ return upliftVanRightGridVerticalPointCount;
+ }
+ set
+ {
+ upliftVanRightGridVerticalPointCount = value;
+ }
+ }
+
+ public double UpliftVanRightGridVerticalPointDistance
+ {
+ get
+ {
+ return upliftVanRightGridVerticalPointDistance;
+ }
+ set
+ {
+ upliftVanRightGridVerticalPointDistance = value;
+ }
+ }
+
+ public int UpliftVanRightGridHorizontalPointCount
+ {
+ get
+ {
+ return upliftVanRightGridHorizontalPointCount;
+ }
+ set
+ {
+ upliftVanRightGridHorizontalPointCount = value;
+ }
+ }
+
+ public double UpliftVanRightGridHorizontalPointDistance
+ {
+ get
+ {
+ return upliftVanRightGridHorizontalPointDistance;
+ }
+ set
+ {
+ upliftVanRightGridHorizontalPointDistance = value;
+ }
+ }
+
+ public int BishopGridVerticalPointCount
+ {
+ get
+ {
+ return bishopGridVerticalPointCount;
+ }
+ set
+ {
+ bishopGridVerticalPointCount = value;
+ }
+ }
+
+ public double BishopGridVerticalPointDistance
+ {
+ get
+ {
+ return bishopGridVerticalPointDistance;
+ }
+ set
+ {
+ bishopGridVerticalPointDistance = value;
+ }
+ }
+
+ public int BishopGridHorizontalPointCount
+ {
+ get
+ {
+ return bishopGridHorizontalPointCount;
+ }
+ set
+ {
+ bishopGridHorizontalPointCount = value;
+ }
+ }
+
+ public double BishopGridHorizontalPointDistance
+ {
+ get
+ {
+ return bishopGridHorizontalPointDistance;
+ }
+ set
+ {
+ bishopGridHorizontalPointDistance = value;
+ }
+ }
+
+ public DamFailureMechanismeCalculationSpecification Specification { get; set; }
+
+ public void Assign(SlipCircleDefinition slipCircleDefinition)
+ {
+ this.XCoordinateLastUpliftPoint = slipCircleDefinition.XCoordinateLastUpliftPoint;
+ this.UpliftVanTangentLinesDefinition = slipCircleDefinition.UpliftVanTangentLinesDefinition;
+ this.UpliftVanTangentLinesDistance = slipCircleDefinition.UpliftVanTangentLinesDistance;
+ this.BishopTangentLinesDefinition = slipCircleDefinition.BishopTangentLinesDefinition;
+ this.BishopTangentLinesDistance = slipCircleDefinition.BishopTangentLinesDistance;
+ this.GridSizeDetermination = slipCircleDefinition.GridSizeDetermination;
+ this.UpliftVanLeftGridVerticalPointCount = slipCircleDefinition.UpliftVanLeftGridVerticalPointCount;
+ this.UpliftVanLeftGridVerticalPointDistance = slipCircleDefinition.UpliftVanLeftGridVerticalPointDistance;
+ this.UpliftVanLeftGridHorizontalPointCount = slipCircleDefinition.UpliftVanLeftGridHorizontalPointCount;
+ this.UpliftVanLeftGridHorizontalPointDistance = slipCircleDefinition.UpliftVanLeftGridHorizontalPointDistance;
+ this.UpliftVanRightGridVerticalPointCount = slipCircleDefinition.UpliftVanRightGridVerticalPointCount;
+ this.UpliftVanRightGridVerticalPointDistance = slipCircleDefinition.UpliftVanRightGridVerticalPointDistance;
+ this.UpliftVanRightGridHorizontalPointCount = slipCircleDefinition.UpliftVanRightGridHorizontalPointCount;
+ this.UpliftVanRightGridHorizontalPointDistance = slipCircleDefinition.UpliftVanRightGridHorizontalPointDistance;
+ this.BishopGridVerticalPointCount = slipCircleDefinition.BishopGridVerticalPointCount;
+ this.BishopGridVerticalPointDistance = slipCircleDefinition.BishopGridVerticalPointDistance;
+ this.BishopGridHorizontalPointCount = slipCircleDefinition.BishopGridHorizontalPointCount;
+ this.BishopGridHorizontalPointDistance = slipCircleDefinition.BishopGridHorizontalPointDistance;
+ }
+
+ public SlipCircleDefinition Clone()
+ {
+ var slipCircleDefinition = new SlipCircleDefinition();
+ slipCircleDefinition.Assign(this);
+ return slipCircleDefinition;
+ }
+ }
+
+ public class MStabZoneAreas : IAssignable, ICloneable
+ {
+ public double DikeTableHeight { get; set; }
+ public double DikeTableWidth { get; set; }
+ public double XCoordinateDikeTopAtRiver { get; set; }
+ public double XCoordinateDikeTopAtPolder { get; set; }
+ public double XCoordinateStartRestProfile { get; set; }
+ public double SafetyFactorZone1A { get; set; }
+ public double SafetyFactorZone1B { get; set; }
+ public void Assign(MStabZoneAreas mstabZoneAreas)
+ {
+ this.DikeTableHeight = mstabZoneAreas.DikeTableHeight;
+ this.DikeTableWidth = mstabZoneAreas.DikeTableWidth;
+ this.XCoordinateDikeTopAtRiver = mstabZoneAreas.XCoordinateDikeTopAtRiver;
+ this.XCoordinateDikeTopAtPolder = mstabZoneAreas.XCoordinateDikeTopAtPolder;
+ this.XCoordinateStartRestProfile = mstabZoneAreas.XCoordinateStartRestProfile;
+ this.SafetyFactorZone1A = mstabZoneAreas.SafetyFactorZone1A;
+ this.SafetyFactorZone1B = mstabZoneAreas.SafetyFactorZone1B;
+ }
+
+ public MStabZoneAreas Clone()
+ {
+ var mstabZoneAreas = new MStabZoneAreas();
+ mstabZoneAreas.Assign(this);
+ return mstabZoneAreas;
+ }
+ }
+
+ public class MStabForbiddenZone : IAssignable, ICloneable
+ {
+ public bool IsXEntryMinUsed { get; set; }
+ public bool IsXEntryMaxUsed { get; set; }
+ public double XEntryMin { get; set; }
+ public double XEntryMax { get; set; }
+ public void Assign(MStabForbiddenZone mstabForbiddenZone)
+ {
+ this.IsXEntryMinUsed = mstabForbiddenZone.IsXEntryMinUsed;
+ this.IsXEntryMaxUsed = mstabForbiddenZone.IsXEntryMaxUsed;
+ this.XEntryMin = mstabForbiddenZone.XEntryMin;
+ this.XEntryMax = mstabForbiddenZone.XEntryMax;
+ }
+
+ public MStabForbiddenZone Clone()
+ {
+ var mstabForbiddenZone = new MStabForbiddenZone();
+ mstabForbiddenZone.Assign(this);
+ return mstabForbiddenZone;
+ }
+ }
+
+ public class MStabDesignEmbankment : IAssignable, ICloneable
+ {
+ public string EmbankmentMaterialname { get; set; }
+ public string PreviousGeometry2DFilename { get; set; }
+ public void Assign(MStabDesignEmbankment mstabDesignEmbankment)
+ {
+ this.EmbankmentMaterialname = mstabDesignEmbankment.EmbankmentMaterialname;
+ this.PreviousGeometry2DFilename = mstabDesignEmbankment.PreviousGeometry2DFilename;
+ }
+
+ public MStabDesignEmbankment Clone()
+ {
+ var mstabDesignEmbankment = new MStabDesignEmbankment();
+ mstabDesignEmbankment.Assign(this);
+ return mstabDesignEmbankment;
+ }
+ }
+
+ public class MStabGeometryCreationOptions : IAssignable, ICloneable
+ {
+ public MStabGeometryCreationOptions()
+ {
+ SoilGeometryType = SoilGeometryType.SoilGeometry1D;
+ SoilGeometry2DFilename = "";
+ XOffsetSoilGeometry2DOrigin = 0.0;
+ MaterialForDike = "";
+ MaterialForShoulder = "";
+ IsUseOriginalPLLineAssignments = false;
+ IsUseOriginalCalculationOptions = false;
+ IsDrySituation = false;
+ PLLineAssignment = PLLineAssignment.ExpertKnowledge;
+ IntrusionVerticalWaterPressureType = IntrusionVerticalWaterPressureType.Standard;
+ PenetrationLength = 0.0;
+ IsDesign = false;
+ }
+ public SoilGeometryType SoilGeometryType { get; set; }
+ public string SoilGeometry2DFilename { get; set; }
+ public double XOffsetSoilGeometry2DOrigin { get; set; }
+ public string MaterialForDike { get; set; }
+ public string MaterialForShoulder { get; set; }
+ public bool IsUseOriginalPLLineAssignments { get; set; }
+ public bool IsUseOriginalCalculationOptions { get; set; }
+ public bool IsDrySituation { get; set; }
+ public PLLineAssignment PLLineAssignment { get; set; }
+ public IntrusionVerticalWaterPressureType IntrusionVerticalWaterPressureType { get; set; }
+ public double PenetrationLength { get; set; }
+ public bool IsDesign { get; set; }
+
+ public void Assign(MStabGeometryCreationOptions mstabGeometryCreationOptions)
+ {
+ this.SoilGeometryType = mstabGeometryCreationOptions.SoilGeometryType;
+ this.SoilGeometry2DFilename = mstabGeometryCreationOptions.SoilGeometry2DFilename;
+ this.XOffsetSoilGeometry2DOrigin = mstabGeometryCreationOptions.XOffsetSoilGeometry2DOrigin;
+ this.MaterialForDike = mstabGeometryCreationOptions.MaterialForDike;
+ this.MaterialForShoulder = mstabGeometryCreationOptions.MaterialForShoulder;
+ this.IsUseOriginalPLLineAssignments = mstabGeometryCreationOptions.IsUseOriginalPLLineAssignments;
+ this.IsUseOriginalCalculationOptions = mstabGeometryCreationOptions.IsUseOriginalCalculationOptions;
+ this.IsDrySituation = mstabGeometryCreationOptions.IsDrySituation;
+ this.PLLineAssignment = mstabGeometryCreationOptions.PLLineAssignment;
+ this.IntrusionVerticalWaterPressureType = mstabGeometryCreationOptions.IntrusionVerticalWaterPressureType;
+ this.PenetrationLength = mstabGeometryCreationOptions.PenetrationLength;
+ this.IsDesign = mstabGeometryCreationOptions.IsDesign;
+ }
+
+ public MStabGeometryCreationOptions Clone()
+ {
+ var mstabGeometryCreationOptions = new MStabGeometryCreationOptions();
+ mstabGeometryCreationOptions.Assign(this);
+ return mstabGeometryCreationOptions;
+ }
+ }
+
+ public class MStabCalculationOptions : IAssignable, ICloneable
+ {
+ public double MinimalCircleDepth { get; set; }
+
+ public MStabZonesType ZonesType { get; set; }
+
+ public void Assign(MStabCalculationOptions mstabCalculationOptions)
+ {
+ this.MinimalCircleDepth = mstabCalculationOptions.MinimalCircleDepth;
+ this.ZonesType = mstabCalculationOptions.ZonesType;
+ }
+
+ public MStabCalculationOptions Clone()
+ {
+ var mstabCalculationOptions = new MStabCalculationOptions();
+ mstabCalculationOptions.Assign(this);
+ return mstabCalculationOptions;
+ }
+ }
+
+ public class MStabParameters : ICloneable
+ {
+ private MStabGridPosition gridPosition;
+
+ public MStabParameters()
+ {
+ this.IsCalculateAllStabilityProjectsAtOnce = true;
+ this.IsOverrulePLLineCreationMethod = false;
+ this.PLLineCreationMethod = PLLineCreationMethod.ExpertKnowledgeRRD;
+ this.Model = MStabModelType.Bishop;
+ this.SearchMethod = MStabSearchMethod.Grid;
+ this.ZoneAreas = null;
+ this.gridPosition = MStabGridPosition.Right;
+ this.CalculationOptions = new MStabCalculationOptions();
+ this.GeometryCreationOptions = new MStabGeometryCreationOptions();
+ this.SheetPiling = null;
+ this.HorizontalBalanceArea = new HorizontalBalanceArea();
+ this.SlipCircleDefinition = new SlipCircleDefinition();
+ }
+
+ public bool IsCombinedBishopUpliftVanCalculation { get { return (Model == MStabModelType.BishopUpliftVan); } }
+ // IsCombinedBishopUpliftVanCalculation (formerly IsAutoSelectCalculation) is the same as Model == MStabModel.BishopUpliftVan
+ // This property was first implemented for FewsDam and later MStabModel.BishopUpliftVan was implemented for normal DAM operation
+ // Now we will use Model == MStabModel.BishopUpliftVan for both FewsDam and DAM
+ // This readonly property is implemented for backward compatibiity
+
+ public bool IsCalculateAllStabilityProjectsAtOnce { get; set; }
+ // Normally PLLine creation is specified per location.
+ // If IsOverrulePLLineCreationMethod is set to true the settings in the locations will be
+ // overruled with the value in PLLineCreationMethod
+ public bool IsOverrulePLLineCreationMethod { get; set; }
+ public PLLineCreationMethod PLLineCreationMethod { get; set; }
+
+ public MStabModelType Model { get; set; }
+
+ public MStabShearStrength ShearStrength { get; set; }
+
+ public MStabSearchMethod SearchMethod { get; set; }
+ public bool IsProbabilistic { get; set; }
+ public string ProjectFileName { get; set; }
+ public string SoilDatabaseName { get; set; }
+ public MStabZoneAreas ZoneAreas { get; set; }
+ public MStabForbiddenZone ForbiddenZone { get; set; }
+ public MStabGeometryCreationOptions GeometryCreationOptions { get; set; }
+ public SheetPiling SheetPiling { get; set; }
+ public HorizontalBalanceArea HorizontalBalanceArea { get; set; }
+
+ [Validate]
+ public SlipCircleDefinition SlipCircleDefinition { get; set; }
+ public MStabCalculationOptions CalculationOptions { get; set; }
+
+ public MStabGridPosition GridPosition
+ {
+ get { return gridPosition; }
+ set
+ {
+ gridPosition = value;
+ }
+ }
+
+ public void Assign(MStabParameters mstabParameters)
+ {
+ this.Model = mstabParameters.Model;
+ this.ShearStrength = mstabParameters.ShearStrength;
+ this.SearchMethod = mstabParameters.SearchMethod;
+ this.IsProbabilistic = mstabParameters.IsProbabilistic;
+ this.GridPosition = mstabParameters.GridPosition;
+ this.ProjectFileName = mstabParameters.ProjectFileName;
+ this.SoilDatabaseName = mstabParameters.SoilDatabaseName;
+ if (this.ZoneAreas != null)
+ {
+ this.ZoneAreas.Assign(mstabParameters.ZoneAreas);
+ }
+ else
+ {
+ this.ZoneAreas = null;
+ }
+ if (this.ForbiddenZone != null)
+ {
+ this.ForbiddenZone.Assign(mstabParameters.ForbiddenZone);
+ }
+ else
+ {
+ this.ForbiddenZone = null;
+ }
+ if (this.CalculationOptions != null)
+ {
+ this.CalculationOptions.Assign(mstabParameters.CalculationOptions);
+ }
+ else
+ {
+ this.CalculationOptions = null;
+ }
+ if (this.GeometryCreationOptions != null)
+ {
+ this.GeometryCreationOptions.Assign(mstabParameters.GeometryCreationOptions);
+ }
+ else
+ {
+ this.GeometryCreationOptions = null;
+ }
+ if (this.SheetPiling != null)
+ {
+ this.SheetPiling.Assign(mstabParameters.SheetPiling);
+ }
+ else
+ {
+ this.SheetPiling = null;
+ }
+ if (this.HorizontalBalanceArea != null)
+ {
+ this.HorizontalBalanceArea.Assign(mstabParameters.HorizontalBalanceArea);
+ }
+ else
+ {
+ this.HorizontalBalanceArea = null;
+ }
+ this.SoilDatabaseName = mstabParameters.SoilDatabaseName;
+ if (this.SlipCircleDefinition != null)
+ {
+ this.SlipCircleDefinition.Assign(mstabParameters.SlipCircleDefinition);
+ }
+ else
+ {
+ this.SlipCircleDefinition = null;
+ }
+ }
+
+ [XmlIgnore]
+ public MStabZonesType ZonesType
+ {
+ get { return this.CalculationOptions.ZonesType; }
+ set { this.CalculationOptions.ZonesType = value; }
+ }
+
+ public MStabParameters Clone()
+ {
+ var mstabParameters = new MStabParameters();
+ if (this.ZoneAreas != null)
+ mstabParameters.ZoneAreas = this.ZoneAreas.Clone();
+ if (this.ForbiddenZone != null)
+ mstabParameters.ForbiddenZone = this.ForbiddenZone.Clone();
+ if (this.GeometryCreationOptions != null)
+ mstabParameters.GeometryCreationOptions = this.GeometryCreationOptions.Clone();
+ if (this.SheetPiling != null)
+ mstabParameters.SheetPiling = this.SheetPiling.Clone();
+ if (this.HorizontalBalanceArea != null)
+ mstabParameters.HorizontalBalanceArea = this.HorizontalBalanceArea.Clone();
+ if (this.SlipCircleDefinition != null)
+ mstabParameters.SlipCircleDefinition = this.SlipCircleDefinition.Clone();
+ if (this.CalculationOptions != null)
+ mstabParameters.CalculationOptions = this.CalculationOptions.Clone();
+
+ mstabParameters.Assign(this);
+
+ return mstabParameters;
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/Routines2D.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/Routines2D.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/Routines2D.cs (revision 334)
@@ -0,0 +1,623 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Type of intersection
+ ///
+ public enum LineIntersection
+ {
+ ///
+ /// The no intersection
+ ///
+ NoIntersection = 0,
+ ///
+ /// The intersects
+ ///
+ Intersects = 1,
+ ///
+ /// The parallel
+ ///
+ Parallel = 2
+ }
+
+ ///
+ /// Position of point towards polygon
+ ///
+ public enum PointInPolygon
+ {
+ ///
+ /// The inside polygon
+ ///
+ InsidePolygon = 0,
+ ///
+ /// The on polygon edge
+ ///
+ OnPolygonEdge = 1,
+ ///
+ /// The outside polygon
+ ///
+ OutsidePolygon = 2
+ }
+
+ ///
+ /// Static class Routines2D
+ ///
+ public static class Routines2D
+ {
+ public struct LineConstant
+ {
+ public double X;
+ public double Y;
+ public double Z;
+ }
+
+ private const double cEpsilon = 1.0e-4;
+
+ ///
+ /// Checks if the 2D Lines strictly intersect. Strictly means that the intersection point must be part of both lines so
+ /// extrapolated points do not count.
+ ///
+ /// The point1 x.
+ /// The point1 z.
+ /// The point2 x.
+ /// The point2 z.
+ /// The point3 x.
+ /// The point3 z.
+ /// The point4 x.
+ /// The point4 z.
+ /// The intersection point.
+ ///
+ /// Intersection status as well as the intersection point (when found, else null)
+ ///
+ ///
+ /// For connected paralllel lines, the connection point will be returned as valid intersection point.
+ ///
+ public static LineIntersection DetermineIf2DLinesIntersectStrickly(double point1X, double point1Z, double point2X, double point2Z,
+ double point3X, double point3Z, double point4X, double point4Z, out Point2D intersectionPoint)
+ {
+ return DetermineIf2DLinesIntersectStrickly(point1X, point1Z, point2X, point2Z, point3X, point3Z, point4X, point4Z,
+ out intersectionPoint, cEpsilon);
+ }
+
+
+ ///
+ /// Doeses the point exist in line.
+ ///
+ /// The line point1 x.
+ /// The line point1 z.
+ /// The line point2 x.
+ /// The line point2 z.
+ /// The point x.
+ /// The point z.
+ /// The tolerance.
+ ///
+ public static bool DoesPointExistInLine(double linePoint1X, double linePoint1Z, double linePoint2X, double linePoint2Z,
+ double pointX, double pointZ, double tolerance)
+ {
+ // Function to find if lies on or close to a line (within a given tolerance)
+ // Input - a line defined by lTwo points, a third point to test and tolerance aValue
+ // Output - TRUE or FALSE
+
+ // first check whether the points are identical
+ if (Math.Abs(linePoint1X - linePoint2X) < tolerance && Math.Abs(linePoint1Z - linePoint2Z) < tolerance)
+ {
+ return Compute2DDistance(pointX, pointZ, linePoint1X, linePoint1Z) < tolerance;
+ }
+
+ // then check if point is within the bounding rectangle formed by 2 line points
+ var maxX = Math.Max(linePoint1X, linePoint2X);
+ var minX = Math.Min(linePoint1X, linePoint2X);
+ var maxY = Math.Max(linePoint1Z, linePoint2Z);
+ var minY = Math.Min(linePoint1Z, linePoint2Z);
+
+ minX -= tolerance;
+ minY -= tolerance;
+ maxX += tolerance;
+ maxY += tolerance;
+
+ var x3 = pointX;
+ var y3 = pointZ;
+
+ if (!(x3 > minX && x3 < maxX && y3 > minY && y3 < maxY))
+ {
+ return false;
+ }
+
+ // check if perpendicular distance between point and line is within tolerance
+ var a = linePoint1Z - linePoint2Z;
+ var b = linePoint2X - linePoint1X;
+ var c = -((a * linePoint1X) + (b * linePoint1Z));
+ var distance = ((a * x3) + (b * y3) + c) / Compute2DDistance(linePoint1X, linePoint1Z, linePoint2X, linePoint2Z);
+
+ return Math.Abs(distance) < tolerance;
+ }
+
+ private static void UndoAddIfNeeded(GeometryLoop polygon, bool needed)
+ {
+ if (needed)
+ {
+ polygon.CalcPoints.Remove(polygon.CalcPoints[polygon.CalcPoints.Count - 1]);
+ }
+ }
+
+ ///
+ /// Find if points Ax,ay are between a boundary polygon.
+ ///
+ /// The polygon.
+ /// The x.
+ /// The z.
+ ///
+ public static PointInPolygon CheckIfPointIsInPolygon(GeometryLoop polygon, double x, double z)
+ {
+ // This is done by calculating and adding the angles from the point to all points
+ // of the polygon (using the ArcTan2 function). If the sum of these angles is
+ // aproximate zero the point lies outside the polygon.
+ // If the sum in aproximate + or - 2Pi the point lies in the polygon;
+ // Performance tests have proven that this algorithm performs better than the
+ // polynomial winding number algorithm described at:
+ // http://geomalgorithms.com/a03-_inclusion.html
+
+ const double epsilon = 1e-10;
+ var result = PointInPolygon.OutsidePolygon;
+
+ // add the last point at the end, cos the polygon must be closed, so the last node equals the first
+ var pointAdded = false;
+ if (polygon.CalcPoints.Count > 0)
+ {
+ if (!polygon.CalcPoints[0].LocationEquals(polygon.CalcPoints[polygon.CalcPoints.Count - 1]))
+ {
+ polygon.CalcPoints.Add(polygon.CalcPoints[0]);
+ pointAdded = true;
+ }
+ }
+
+ var polygonPoints = polygon.CalcPoints.Count;
+ if (polygonPoints > 2)
+ {
+ var deltaX = polygon[0].X - x;
+ var deltaZ = polygon[0].Z - z;
+ var absX = Math.Abs(deltaX);
+ var absZ = Math.Abs(deltaZ);
+ if ((absX < epsilon) && (absZ < epsilon))
+ {
+ UndoAddIfNeeded(polygon, pointAdded);
+ return PointInPolygon.OnPolygonEdge;
+ }
+
+ var al1 = Math.Atan2(deltaZ, deltaX);
+ double som = 0;
+ var index = 1;
+
+ while (index < polygonPoints)
+ {
+ deltaX = polygon[index].X - x;
+ deltaZ = polygon[index].Z - z;
+ absX = Math.Abs(deltaX);
+ absZ = Math.Abs(deltaZ);
+ if ((absX < epsilon) && (absZ < epsilon))
+ {
+ UndoAddIfNeeded(polygon, pointAdded);
+ return PointInPolygon.OnPolygonEdge;
+ }
+ var al2 = Math.Atan2(deltaZ, deltaX);
+ var al3 = al2 - al1;
+
+ if (al3 < -Math.PI)
+ {
+ al3 = al3 + (2.0*Math.PI);
+ }
+ if (al3 > Math.PI)
+ {
+ al3 = al3 - (2.0*Math.PI);
+ }
+ if (((Math.PI - al3) < epsilon) || ((Math.PI + al3) < epsilon))
+ {
+ UndoAddIfNeeded(polygon, pointAdded);
+ return PointInPolygon.OnPolygonEdge;
+ }
+ som = som + al3;
+ al1 = al2;
+ index++;
+ }
+
+ if ((som > (1.9*Math.PI)) || (som < (-1.9*Math.PI)))
+ {
+ result = PointInPolygon.InsidePolygon;
+ }
+ else
+ {
+ result = PointInPolygon.OutsidePolygon;
+ }
+ }
+ UndoAddIfNeeded(polygon, pointAdded);
+ return result;
+ }
+
+ ///
+ /// Intersection of Circle and line
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static List IntersectCircleline(double aX, double aY, double aR, double aX1, double aX2, double aY1, double aY2)
+ {
+ // Solve by filling in parametric equation of line :
+ // X = x1 + u*(x2 - x1)
+ // Y = y1 + u*(y2 - y1)
+ // Compare it to that of a cricle:
+ // (X - xm)^2 + (Y - ym)^2 = r^2
+ // And check solve for parameter u in a quadratic equation.
+ // - no solutions => no intersections
+ // - one or two solutions => intersection when -eps <= u <= 1+eps.
+ // If (x1,y1) close to circle edge, return (x1,y1).
+
+ const double lAbcEps = 1E-8;
+ var lX1 = aX2 - aX1;
+ var lX2 = aX1 - aX;
+ var lY1 = aY2 - aY1;
+ var lY2 = aY1 - aY;
+ var result = new List();
+ if ((Math.Abs(lX1) > lAbcEps) || (Math.Abs(lY1) > lAbcEps))
+ {
+ var lA = lX1*lX1 + lY1*lY1;
+ var lB = 2*(lX1*lX2 + lY1*lY2);
+ var lC = lX2*lX2 + lY2*lY2 - aR*aR;
+ var lD = lB*lB - 4*lA*lC;
+
+ if (lD > lAbcEps)
+ {
+ var lU = (-lB + Math.Sqrt(lD))/(2*lA);
+ if ((lU >= -lAbcEps) && (lU <= (1.0 + lAbcEps)))
+ {
+ result.Add(new Point2D{ X= aX1 + lU*lX1, Z = aY1 + lU*lY1});
+ }
+ lU = (-lB - Math.Sqrt(lD))/(2*lA);
+
+ if ((lU >= -lAbcEps) && (lU <= (1.0 + lAbcEps)))
+ {
+ result.Add(new Point2D{ X = aX1 + lU*lX1, Z = aY1 + lU*lY1});
+ }
+ }
+ else if (Math.Abs(lD) <= lAbcEps)
+ {
+ var lU = (-lB)/(2*lA);
+ if ((lU >= -lAbcEps) && (lU <= 1.0 + lAbcEps))
+ {
+ result.Add(new Point2D { X = aX1 + lU*lX1, Z = aY1 + lU*lY1});
+ }
+ }
+ }
+ else if (Math.Abs(Math.Pow(lX2, 2) + Math.Pow(lY2, 2) - Math.Pow(aR, 2)) < lAbcEps)
+ {
+ result.Add(new Point2D() {X = aX1, Z = aY1});
+ }
+ return result;
+ }
+
+
+ ///
+ /// Checks if values are equal
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static bool AreEqual(double x1, double x2, double tolerance)
+ {
+ return (Math.Abs(x1 - x2) < tolerance);
+ }
+
+ ///
+ /// Takes the cross product of two vectors
+ ///
+ /// X-coordinate of the first point
+ /// Y-coordinate of the first point
+ /// X-coordinate of the second point
+ /// Y-coordinate of the second point
+ ///
+ private static double CrossProduct(double pointAx, double pointAy, double pointBx, double pointBy)
+ {
+ return pointAx*pointBy - pointBx*pointAy;
+ }
+
+ ///
+ /// Description: Finds the Normal. FPoint1 and FPoint2 are the line coordinates
+ ///
+ /// The point1 x.
+ /// The point1 z.
+ /// The point2 x.
+ /// The point2 z.
+ ///
+ private static LineConstant CalculateNormalLineConstants(double point1X, double point1Z, double point2X, double point2Z)
+ {
+ var lLineConstant = new LineConstant
+ {
+ X = point2Z - point1Z,
+ Y = -(point2X - point1X),
+ Z = (point2Z - point1Z) * point1X - (point2X - point1X) * point1Z
+ };
+
+ return lLineConstant;
+ }
+
+ ///
+ /// Checks if lTwo lines are parallel. The Normal Line Constants are required.
+ ///
+ /// a line1 constant x.
+ /// a line1 constant y.
+ /// a line2 constant x.
+ /// a line2 constant y.
+ /// The tolerance.
+ ///
+ private static bool AreLinesParallel(double aLine1ConstantX, double aLine1ConstantY, double aLine2ConstantX, double aLine2ConstantY, double tolerance)
+ {
+ 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.
+ /// Note that parallel lines never return an intersection point, not even when there two parallel lines are neatly connected.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static LineIntersection DetermineIf2DLinesIntersectWithExtrapolation(LineConstant aLine1Constant, LineConstant aLine2Constant, out Point2D aIntersectionPoint)
+ {
+ aIntersectionPoint = new Point2D(0.0, 0.0);
+
+ var lA1 = aLine1Constant.X;
+ var lB1 = aLine1Constant.Y;
+ var lC1 = aLine1Constant.Z;
+ var lA2 = aLine2Constant.X;
+ var lB2 = aLine2Constant.Y;
+ var lC2 = aLine2Constant.Z;
+
+ if (AreLinesParallel(lA1, lA2, lB1, lB2, cEpsilon))
+ {
+ aIntersectionPoint = null;
+ return LineIntersection.Parallel;
+ }
+
+ var lX = (lB2*lC1 - lB1*lC2)/(lA1*lB2 - lA2*lB1);
+ var lY = (lC1*lA2 - lC2*lA1)/(lA2*lB1 - lA1*lB2);
+
+ aIntersectionPoint.X = lX;
+ aIntersectionPoint.Z = lY;
+
+ return LineIntersection.Intersects;
+ }
+
+ ///
+ /// Calculates the Euclidean distance between two points on a 2-dimensional plane
+ ///
+ /// X-coordinate of the first point
+ /// Y-coordinate of the first point
+ /// X-coordinate of the second point
+ /// Y-coordinate of the second point
+ /// The distance between the given points.
+ private static double Compute2DDistance(double aX1, double aY1, double aX2, double aY2)
+ {
+ var lX = aX1 - aX2;
+ var lY = aY1 - aY2;
+
+ return Math.Sqrt(lX * lX + lY * lY);
+ }
+
+ ///
+ /// Checks if the 2D Lines strictly intersect. Strictly means that the intersection point must be part of both lines so
+ /// extrapolated points do not count.
+ ///
+ /// The point1 x.
+ /// The point1 z.
+ /// The point2 x.
+ /// The point2 z.
+ /// The point3 x.
+ /// The point3 zx.
+ /// The point4 x.
+ /// The point4 z.
+ /// The intersection point.
+ /// Non-inclusive maximum allowed distance between two possibly intersecting endpoints of the lines
+ ///
+ /// Intersection status as well as the intersection point (when found, else null)
+ ///
+ ///
+ /// For connected paralllel lines, the connection point will be returned as valid intersection point.
+ ///
+ private static LineIntersection DetermineIf2DLinesIntersectStrickly(double point1X, double point1Z, double point2X, double point2Z,
+ double point3X, double point3Z, double point4X, double point4Z, out Point2D intersectionPoint, double tolerance)
+ {
+ var lineConstant1 = CalculateNormalLineConstants(point1X, point1Z, point2X, point2Z);
+ var lineConstant2 = CalculateNormalLineConstants(point3X, point3Z, point4X, point4Z);
+
+ var result = DetermineIf2DLinesIntersectWithExtrapolation(lineConstant1, lineConstant2, out intersectionPoint);
+
+ if (result == LineIntersection.Intersects)
+ {
+ //check if lies on the line and is not somewhere outside !
+ if ((DoesPointExistInLine(point1X, point1Z, point2X, point2Z, intersectionPoint.X, intersectionPoint.Z, tolerance) &&
+ DoesPointExistInLine(point3X, point3Z, point4X, point4Z, intersectionPoint.X, intersectionPoint.Z, tolerance)) == false)
+ {
+ intersectionPoint = null;
+ result = LineIntersection.NoIntersection;
+ }
+ }
+ else
+ {
+ if (result == LineIntersection.Parallel && !DoLinesAtLeastPartialyOverlap(point1X, point1Z, point2X, point2Z, point3X, point3Z,
+ point4X, point4Z, tolerance))
+ {
+ if (DetermineIfPointsCoincide(point1X, point1Z, point3X, point3Z, tolerance) ||
+ DetermineIfPointsCoincide(point1X, point1Z, point4X, point4Z, tolerance))
+ {
+ intersectionPoint = new Point2D(point1X, point1Z);
+ result = LineIntersection.Intersects;
+ }
+ if (DetermineIfPointsCoincide(point2X, point2Z, point3X, point3Z, tolerance) ||
+ DetermineIfPointsCoincide(point2X, point2Z, point4X, point4Z, tolerance))
+ {
+ intersectionPoint = new Point2D(point2X, point2Z);
+ result = LineIntersection.Intersects;
+ }
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// Determines whether the given lines at least partialy overlap.
+ /// Note that purely connected parallel lines are NOT considered to be overlapping.
+ ///
+ /// The point1 x.
+ /// The point1 z.
+ /// The point2 x.
+ /// The point2 z.
+ /// The point3 x.
+ /// The point3 z.
+ /// The point4 x.
+ /// The point4 z.
+ /// The tolerance.
+ ///
+ private static bool DoLinesAtLeastPartialyOverlap(double point1X, double point1Z, double point2X, double point2Z,
+ double point3X, double point3Z, double point4X, double point4Z, double tolerance)
+ {
+ var result = AreLinesParallel(point1X, point1Z, point2X, point2Z, point3X, point3Z, point4X, point4Z, tolerance);
+
+ // lines not parallel so can not overlap
+ if (!result)
+ {
+ return false;
+ }
+
+ if (Math.Abs(point1X - point2X) < double.Epsilon)
+ {
+ // lines are vertical so check Y values
+ var max12 = Math.Max(point1Z, point2Z);
+ var min12 = Math.Min(point1Z, point2Z);
+ var max34 = Math.Max(point3Z, point4Z);
+ var min34 = Math.Min(point3Z, point4Z);
+ // When max of point1/point2 does not exceed min of point3/point4 lines do not overlap
+ // When max of point3/point4 does not exceed min of point1/point2 lines do not overlap
+ if (max12 <= min34 || min12 >= max34)
+ {
+ result = false;
+ }
+ }
+ else
+ {
+ // lines are not vertical so check X values
+ var max12 = Math.Max(point1X, point2X);
+ var min12 = Math.Min(point1X, point2X);
+ var max34 = Math.Max(point3X, point4X);
+ var min34 = Math.Min(point3X, point4X);
+ if (max12 <= min34 || min12 >= max34)
+ {
+ result = false;
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// Description: Checks if two lines are parallel within the given tolerance
+ ///
+ /// The point1 x.
+ /// The point1 z.
+ /// The point2 x.
+ /// The point2 z.
+ /// The point3 x.
+ /// The point3 z.
+ /// The point4 x.
+ /// The point4 z.
+ /// The tolerance.
+ ///
+ /// True when parallel
+ ///
+ private static bool AreLinesParallel(double point1X, double point1Z, double point2X, double point2Z,
+ double point3X, double point3Z, double point4X, double point4Z, double tolerance)
+ {
+
+ double aX = point2X - point1X;
+ double aY = point2Z - point1Z;
+
+ double bX = point4X - point3X;
+ double bY = point4Z - point3Z;
+
+ Normalize(ref aX, ref aY);
+ Normalize(ref bX, ref bY);
+ return AreLinesParallel(aX, aY, bX, bY, tolerance);
+ }
+
+ ///
+ /// Normalizes this instance.
+ ///
+ private static void Normalize(ref double pointX, ref double pointY)
+ {
+ double q = Math.Sqrt(pointX * pointX + pointY * pointY);
+
+ if (q != 0)
+ {
+ pointX = pointX / q;
+ pointY = pointY / q;
+ }
+ }
+
+ ///
+ /// Checks if the points coincide
+ ///
+ /// The point1 x.
+ /// The point1 z.
+ /// The point2 x.
+ /// The point2 z.
+ /// The tolerance.
+ ///
+ private static bool DetermineIfPointsCoincide(double point1X, double point1Z, double point2X, double point2Z, double tolerance)
+ {
+ if ((Math.Abs(point1X - point2X)) < tolerance && Math.Abs(point1Z - point2Z) < tolerance)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/LocationResult.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/LocationResult.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/LocationResult.cs (revision 334)
@@ -0,0 +1,74 @@
+// 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 Deltares.DamEngine.Data.General.TimeSeries;
+using Deltares.DamEngine.Data.RWScenarios;
+
+namespace Deltares.DamEngine.Data.General.Results
+{
+ public class LocationResult
+ {
+ private TimeSerie stabilityTimeSerie = new TimeSerie();
+ private TimeSerie pipingTimeSerie = new TimeSerie();
+ private RWScenariosResult rwScenariosResult = null;
+ private RWSchematizationFactorsResult schematizationFactorsResult = null;
+
+ public LocationResult()
+ {
+ }
+
+ public virtual TimeSerie StabilityTimeSerie
+ {
+ get { return stabilityTimeSerie; }
+ set
+ {
+ stabilityTimeSerie = value;
+ }
+ }
+
+ public TimeSerie PipingTimeSerie
+ {
+ get { return pipingTimeSerie; }
+ set
+ {
+ pipingTimeSerie = value;
+ }
+ }
+
+ public virtual RWScenariosResult RWScenariosResult
+ {
+ get { return rwScenariosResult; }
+ set
+ {
+ rwScenariosResult = value;
+ }
+ }
+
+ public RWSchematizationFactorsResult SchematizationFactorsResult
+ {
+ get { return schematizationFactorsResult; }
+ set
+ {
+ schematizationFactorsResult = value;
+ }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorData.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorData.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorData.cs (revision 334)
@@ -0,0 +1,111 @@
+// 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.ComponentModel;
+using System.Linq;
+
+namespace Deltares.DamEngine.Data.General.Sensors
+{
+ ///
+ /// Class to hold the collected sensor data
+ ///
+ public class SensorData
+ {
+ private List sensors = new List();
+ private List sensorGroups = new List();
+ private List sensorLocations = new List();
+
+ ///
+ /// Updates the pick sensors for groups.
+ ///
+ public void UpdatePickSensorsForGroups()
+ {
+ foreach (var sensorGroup in sensorGroups)
+ {
+ sensorGroup.PickSensors = sensors;
+ }
+ }
+
+ ///
+ /// Gets or sets the sensors.
+ ///
+ ///
+ /// The sensors.
+ ///
+ public List Sensors
+ {
+ get { return sensors; }
+ set { sensors = value; }
+ }
+
+ ///
+ /// Gets or sets the sensor groups.
+ ///
+ ///
+ /// The sensor groups.
+ ///
+ public List SensorGroups
+ {
+ get { return sensorGroups; }
+ set { sensorGroups = value; }
+ }
+
+ ///
+ /// Gets or sets the sensor locations.
+ ///
+ ///
+ /// The sensor locations.
+ ///
+ public List SensorLocations
+ {
+ get { return sensorLocations; }
+ }
+
+ public Sensor GetSensorById(int id)
+ {
+ return sensors.FirstOrDefault(sensor => sensor.ID == id);
+ }
+
+ public Group GetGroupById(int id)
+ {
+ return sensorGroups.FirstOrDefault(sensorGroup => sensorGroup.ID == id);
+ }
+
+ public SensorLocation GetSensorLocationByLocationName(string name)
+ {
+ return sensorLocations.FirstOrDefault(sensorLocation => sensorLocation.LocationName == name);
+ }
+
+ ///
+ /// Gets the groups for use in selection lists in de UI.
+ ///
+ /// The sensoLocation.
+ ///
+ public IEnumerable GetGroups(SensorLocation sensorLocation)
+ {
+ var list = new List();
+ list.AddRange(sensorGroups);
+ return list;
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Design/CsvExportData.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Design/CsvExportData.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Design/CsvExportData.cs (revision 334)
@@ -0,0 +1,1907 @@
+// 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.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.Results;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Geotechnics;
+using Deltares.DamEngine.Data.Standard.Calculation;
+
+namespace Deltares.DamEngine.Data.Design
+{
+ ///
+ ///1:"Id":invoer
+ ///2:"Dijkringnaam":invoer
+ ///3:"RDX":invoer
+ ///4:"RDY":invoer
+ ///5:"Scenarionummer (waterhoogtenummer, hoeveelste \"entry\" uit tabel; 1, 2, 3, 4 of 5)":invoer
+ ///6:"Waterhoogtewaarde":invoer
+ ///7:"Dijkhoogte bestaand":invoer
+ ///8:"Huidige locatie teen":invoer
+ ///9:"Dijktafelhoogte":invoer
+ ///10:"1Dprofiel":invoer
+ ///11:"Mechanisme":invoer
+ ///12:"1Dprofiel kans":invoer
+ ///13:"Berekende lokatie teen":uitvoer
+ ///14:"Bermhoogte":uitvoer
+ ///15:"Dijkbasis bestaand":invoer
+ ///16:"Dijkbasis nieuw":uitvoer
+ ///
+ public class CsvExportData : ICloneable
+ {
+ private string id;
+ private string baseFileName;
+ private string calculationSubDir;
+ private Dike dike;
+ private AnalysisType analysisType;
+ private ProbabilisticType probabilisticType;
+ private DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification;
+ private Scenario scenario;
+ private SoilProfile1D soilProfile;
+ private string soilGeometry2DName;
+ private double? safetyFactorFlowSlide;
+ private double? failureProbabilityPiping;
+ private double? localPipingExitPointX;
+ private SurfaceLine2 redesignedSurfaceLinePiping;
+ private double? safetyFactorStability;
+ private double? failureProbabilityStability;
+ private double? zone1SafetyFactorStability;
+ private double? localZone1EntryPointX;
+ private double? localZone1ExitPointX;
+ private double? zone2SafetyFactorStability;
+ private double? localZone2EntryPointX;
+ private double? localZone2ExitPointX;
+ private double? upliftFactor;
+ private double? heaveFactor;
+ private double? blighPipingFactor;
+ private double? blighHCritical;
+ private double? sellmeijer2ForcesPipingFactor;
+ private double? sellmeijer2ForcesHCritical;
+ private double? sellmeijer4ForcesPipingFactor;
+ private double? sellmeijer4ForcesHCritical;
+ private double? sellmeijerPipingFactor;
+ private double? sellmeijerHCritical;
+ private double? wti2017PipingFactor;
+ private double? wti2017HCritical;
+ private bool? isUplift;
+ private double? pl3MinUplift;
+ private double? pl3HeadAdjusted;
+ private double? pl3LocalLocationXMinUplift;
+ private double? pl4MinUplift;
+ private double? pl4HeadAdjusted;
+ private double? pl4LocalLocationXMinUplift;
+ private readonly string nwoId;
+ private readonly int nwoResultIndex;
+ private double? locationXrdStart;
+ private double? locationYrdStart;
+ private readonly double? locationZrdStart;
+ private double? locationXrdEnd;
+ private double? locationYrdEnd;
+ private readonly double? locationZrdEnd;
+ private CalculationResult calculationResult = CalculationResult.NoRun;
+ private string resultMessage = "";
+ private int numberOfIterations;
+ private ResultEvaluation resultEvaluation = ResultEvaluation.NotEvaluated;
+ private string notes = "";
+ private bool dirty = true;
+ private List points = new List();
+ private StabilityKernelType selectedStabilityKernelType = StabilityKernelType.DamClassic;
+ private SurfaceLine2 redesignedSurfaceLineStability;
+
+ public CsvExportData()
+ {
+ }
+
+ public CsvExportData(string id, Dike dike, DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification, Scenario scenario, SoilProfile1D soilProfile,
+ string soilGeometry2DName, AnalysisType analysisType, int nwoResultIndex, ProbabilisticType probabilisticType)
+ {
+ this.id = id;
+ this.BaseFileName = "";
+ this.CalculationSubDir = "";
+ this.dike = dike;
+ this.damFailureMechanismeCalculationSpecification = damFailureMechanismeCalculationSpecification;
+ this.scenario = scenario;
+ this.soilProfile = soilProfile;
+ this.SoilGeometry2DName = soilGeometry2DName;
+ this.analysisType = analysisType;
+ this.failureProbabilityPiping = null;
+ this.redesignedSurfaceLinePiping = null;
+ this.safetyFactorStability = null;
+ this.failureProbabilityStability = null;
+ this.redesignedSurfaceLineStability = null;
+ this.zone1SafetyFactorStability = null;
+ this.LocalZone1EntryPointX = null;
+ this.LocalZone1ExitPointX = null;
+ this.zone2SafetyFactorStability = null;
+ this.LocalZone2EntryPointX = null;
+ this.LocalZone2ExitPointX = null;
+ this.blighPipingFactor = null;
+ this.blighHCritical = null;
+ this.sellmeijer2ForcesPipingFactor = null;
+ this.sellmeijer2ForcesHCritical = null;
+ this.sellmeijer4ForcesPipingFactor = null;
+ this.sellmeijer4ForcesHCritical = null;
+ this.sellmeijerPipingFactor = null;
+ this.sellmeijerHCritical = null;
+ this.wti2017PipingFactor = null;
+ this.wti2017HCritical = null;
+ this.isUplift = null;
+ this.pl3MinUplift = null;
+ this.pl3HeadAdjusted = null;
+ this.pl3LocalLocationXMinUplift = null;
+ this.pl4MinUplift = null;
+ this.pl4HeadAdjusted = null;
+ this.pl4LocalLocationXMinUplift = null;
+ this.nwoId = "";
+ this.nwoResultIndex = nwoResultIndex;
+ this.locationXrdStart = null;
+ this.locationXrdEnd = null;
+ this.locationYrdStart = null;
+ this.locationYrdEnd = null;
+ this.locationZrdStart = null;
+ this.locationZrdEnd = null;
+ this.dirty = true;
+
+ if (damFailureMechanismeCalculationSpecification != null)
+ {
+ this.probabilisticType = probabilisticType;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ case FailureMechanismSystemType.StabilityOutside:
+
+ if (analysisType == AnalysisType.AdaptNWO)
+ {
+ // an index of 0 can also indicate an error message. That has no futher data so check if there actualy is any.
+ if (scenario.NwoResults.Count > 0)
+ {
+ this.nwoId = scenario.NwoResults[nwoResultIndex].NwoId;
+ this.locationXrdStart = scenario.NwoResults[nwoResultIndex].LocationXrdStart;
+ this.locationYrdStart = scenario.NwoResults[nwoResultIndex].LocationYrdStart;
+ this.locationZrdStart = scenario.NwoResults[nwoResultIndex].LocationZrdStart;
+ this.locationXrdEnd = scenario.NwoResults[nwoResultIndex].LocationXrdEnd;
+ this.locationYrdEnd = scenario.NwoResults[nwoResultIndex].LocationYrdEnd;
+ this.locationZrdEnd = scenario.NwoResults[nwoResultIndex].LocationZrdEnd;
+ this.dirty = true;
+ this.BaseFileName = scenario.NwoResults[nwoResultIndex].MStabResults.CalculationName;
+ this.CalculationSubDir =
+ scenario.NwoResults[nwoResultIndex].MStabResults.CalculationSubDir;
+ this.numberOfIterations =
+ scenario.NwoResults[nwoResultIndex].MStabResults.IterationNumber;
+ this.safetyFactorStability = scenario.NwoResults[nwoResultIndex].MStabResults.zone1.safetyFactor;
+ this.zone1SafetyFactorStability = scenario.NwoResults[nwoResultIndex].MStabResults.zone1.safetyFactor;
+ this.LocalZone1EntryPointX = scenario.NwoResults[nwoResultIndex].MStabResults.zone1.entryPointXCoordinate;
+ this.LocalZone1ExitPointX = scenario.NwoResults[nwoResultIndex].MStabResults.zone1.exitPointXCoordinate;
+ if (scenario.NwoResults[nwoResultIndex].MStabResults.zone2 != null)
+ {
+ this.zone2SafetyFactorStability = scenario.NwoResults[nwoResultIndex].MStabResults.zone2.Value.safetyFactor;
+ this.LocalZone2EntryPointX = scenario.NwoResults[nwoResultIndex].MStabResults.zone2.Value.entryPointXCoordinate;
+ this.LocalZone2ExitPointX = scenario.NwoResults[nwoResultIndex].MStabResults.zone2.Value.exitPointXCoordinate;
+ }
+ }
+ }
+ else
+ {
+ MStabResults? mstabResults = scenario.GetMStabResults(this.SoilProfile, this.SoilGeometry2DName);
+ this.resultMessage = scenario.GetResultMessage(this.SoilProfile, this.SoilGeometry2DName);
+ calculationResult = DetermineStabilityCalculationResult(this.resultMessage, mstabResults);
+ if (mstabResults != null)
+ {
+
+ BaseFileName = mstabResults.Value.CalculationName;
+ CalculationSubDir = mstabResults.Value.CalculationSubDir;
+ numberOfIterations = mstabResults.Value.IterationNumber;
+ this.safetyFactorStability = mstabResults.Value.zone1.safetyFactor;
+ this.zone1SafetyFactorStability = mstabResults.Value.zone1.safetyFactor;
+ this.LocalZone1EntryPointX = mstabResults.Value.zone1.entryPointXCoordinate;
+ this.LocalZone1ExitPointX = mstabResults.Value.zone1.exitPointXCoordinate;
+ if (mstabResults.Value.zone2 != null)
+ {
+ this.zone2SafetyFactorStability = mstabResults.Value.zone2.Value.safetyFactor;
+ this.LocalZone2EntryPointX = mstabResults.Value.zone2.Value.entryPointXCoordinate;
+ this.LocalZone2ExitPointX = mstabResults.Value.zone2.Value.exitPointXCoordinate;
+ }
+ }
+ }
+ this.failureProbabilityStability = scenario.GetFailureProbabilityStability(this.SoilProfile, this.SoilGeometry2DName);
+ this.redesignedSurfaceLineStability = scenario.GetRedesignedSurfaceLine(this.SoilProfile, this.SoilGeometry2DName);
+
+ UpliftSituation? upliftSituation = scenario.GetStabilityUpliftSituation(this.SoilProfile, this.SoilGeometry2DName);
+ if (upliftSituation != null)
+ {
+ SetUpliftSituationResults(upliftSituation.Value);
+ }
+
+ break;
+
+ case FailureMechanismSystemType.Piping:
+
+ this.failureProbabilityPiping = scenario.GetFailureProbabilityPiping(this.SoilProfile, this.SoilGeometry2DName);
+ this.resultMessage = scenario.GetResultMessage(this.SoilProfile, this.SoilGeometry2DName);
+ this.redesignedSurfaceLinePiping = scenario.GetRedesignedSurfaceLine(this.SoilProfile, this.SoilGeometry2DName);
+ UpliftSituation? upliftSituationPiping = scenario.GetStabilityUpliftSituation(this.SoilProfile, this.SoilGeometry2DName);
+ if (upliftSituationPiping != null)
+ {
+ SetUpliftSituationResults(upliftSituationPiping.Value);
+ }
+ PipingResults? pipingResults = scenario.GetPipingResults(this.SoilProfile, this.SoilGeometry2DName);
+ if (pipingResults != null)
+ {
+ BaseFileName = pipingResults.Value.CalculationName;
+ CalculationSubDir = pipingResults.Value.CalculationSubDir;
+ this.blighPipingFactor = pipingResults.Value.BlighPipingFactor;
+ this.blighHCritical = pipingResults.Value.BlighHCritical;
+ this.sellmeijer2ForcesPipingFactor = pipingResults.Value.Sellmeijer2ForcesPipingFactor;
+ this.sellmeijer2ForcesHCritical = pipingResults.Value.Sellmeijer2ForcesHCritical;
+ this.sellmeijer4ForcesPipingFactor = pipingResults.Value.Sellmeijer4ForcesPipingFactor;
+ this.sellmeijer4ForcesHCritical = pipingResults.Value.Sellmeijer4ForcesHCritical;
+ this.sellmeijerPipingFactor = pipingResults.Value.SellmeijerPipingFactor;
+ this.sellmeijerHCritical = pipingResults.Value.SellmeijerHCritical;
+ this.wti2017PipingFactor = pipingResults.Value.Wti2017PipingFactor;
+ this.wti2017HCritical = pipingResults.Value.Wti2017HCritical;
+ this.localPipingExitPointX = pipingResults.Value.PipingExitPointX;
+ this.HeaveFactor = pipingResults.Value.HeaveFactor;
+ this.UpliftFactor = pipingResults.Value.UpliftFactor;
+ }
+ this.calculationResult = (this.PipingFactor == null && this.PipingFailureProbability == null) ? CalculationResult.RunFailed : CalculationResult.Succeeded;
+ break;
+ case FailureMechanismSystemType.FlowSlide:
+ this.safetyFactorFlowSlide = scenario.GetSafetyFactorFlowSlide(this.SoilProfile, this.SoilGeometry2DName);
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Determines the global point coordinates based on global surface line.
+ ///
+ /// The local point.
+ /// The global surface line.
+ ///
+ private GeometryPoint DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(GeometryPoint localPoint, SurfaceLine2 globalSurfaceLine)
+ {
+ CoordinateSystemConverter coordinateSystemConverter = new CoordinateSystemConverter();
+ coordinateSystemConverter.DefineGlobalXYZBasedOnLine(globalSurfaceLine.Geometry);
+
+ coordinateSystemConverter.ConvertLocalXZToGlobalXYZ(localPoint);
+ return localPoint;
+ }
+
+ ///
+ /// Determines the stability calculation run result.
+ ///
+ /// The result message.
+ /// The mstab results.
+ ///
+ private CalculationResult DetermineStabilityCalculationResult(string message, MStabResults? mstabResults)
+ {
+ CalculationResult result;
+ if ((message != null) && this.resultMessage.Contains("FAIL"))
+ {
+ result = CalculationResult.UnexpectedError;
+ }
+ else
+ {
+ // If no failure and no results, then no run has been made
+ result = mstabResults != null ? CalculationResult.Succeeded : CalculationResult.NoRun;
+ }
+ return result;
+ }
+
+ ///
+ /// Sets the uplift situation results.
+ ///
+ /// The uplift situation.
+ private void SetUpliftSituationResults(UpliftSituation upliftSituation)
+ {
+ this.isUplift = upliftSituation.IsUplift;
+ if (upliftSituation.Pl3MinUplift < double.MaxValue)
+ {
+ this.pl3MinUplift = upliftSituation.Pl3MinUplift;
+ }
+ if (upliftSituation.Pl3HeadAdjusted < double.MaxValue)
+ {
+ this.pl3HeadAdjusted = upliftSituation.Pl3HeadAdjusted;
+ }
+ if (upliftSituation.Pl3LocationXMinUplift < double.MaxValue)
+ {
+ this.pl3LocalLocationXMinUplift = upliftSituation.Pl3LocationXMinUplift;
+ }
+ if (upliftSituation.Pl4MinUplift < double.MaxValue)
+ {
+ this.pl4MinUplift = upliftSituation.Pl4MinUplift;
+ }
+ if (upliftSituation.Pl4HeadAdjusted < double.MaxValue)
+ {
+ this.pl4HeadAdjusted = upliftSituation.Pl4HeadAdjusted;
+ }
+ if (upliftSituation.Pl4LocationXMinUplift < double.MaxValue)
+ {
+ this.pl4LocalLocationXMinUplift = upliftSituation.Pl4LocationXMinUplift;
+ }
+ }
+
+ public StabilityKernelType SelectedStabilityKernelType
+ {
+ get { return selectedStabilityKernelType; }
+ set { selectedStabilityKernelType = value; }
+ }
+
+ public int NumberOfIterations
+ {
+ get { return numberOfIterations; }
+ set { numberOfIterations = value; }
+ }
+
+ public string ResultFile
+ {
+ get
+ {
+ if (!String.IsNullOrEmpty(BaseFileName))
+ {
+ const string wmfExtension = ".wmf";
+ string fullBaseFilename = DamProjectData.ProjectWorkingPath;
+ if (CalculationSubDir != "")
+ {
+ fullBaseFilename = Path.Combine(fullBaseFilename, CalculationSubDir);
+ }
+ fullBaseFilename = fullBaseFilename + Path.DirectorySeparatorChar + BaseFileName;
+ string fullFilename = fullBaseFilename + wmfExtension;
+ if (!File.Exists(fullFilename))
+ {
+ fullFilename = fullBaseFilename + "z1" + wmfExtension;
+ }
+ if (!File.Exists(fullFilename))
+ {
+ fullFilename = fullBaseFilename + "z2" + wmfExtension;
+ }
+ return fullFilename;
+ }
+ return "";
+ }
+ }
+
+ public string InputFile
+ {
+ get
+ {
+ if (!String.IsNullOrEmpty(BaseFileName))
+ {
+ string fileExtension = ".sti";
+ if (selectedStabilityKernelType != StabilityKernelType.DamClassic)
+ {
+ fileExtension = ".dsx";
+ }
+ string fullBaseFilename = DamProjectData.ProjectWorkingPath;
+ if (CalculationSubDir != "")
+ {
+ fullBaseFilename = Path.Combine(fullBaseFilename, CalculationSubDir);
+ }
+ fullBaseFilename = fullBaseFilename + Path.DirectorySeparatorChar + BaseFileName;
+ string fullFilename = fullBaseFilename + fileExtension;
+ return fullFilename;
+ }
+ return "";
+ }
+ }
+
+ public string PipingResultFile
+ {
+ // Path of piping is not based on the working dir but on assembly (Assembly.GetExecutingAssembly().Location)
+ get
+ {
+ if (!String.IsNullOrEmpty(BaseFileName))
+ {
+ const string txtExtension = ".txt";
+ string fullBaseFilename = DamProjectData.ProjectWorkingPath;
+ if (CalculationSubDir != "")
+ {
+ fullBaseFilename = Path.Combine(fullBaseFilename, CalculationSubDir);
+ }
+ fullBaseFilename = fullBaseFilename + Path.DirectorySeparatorChar + BaseFileName;
+ string fullFilename = fullBaseFilename + txtExtension;
+ return fullFilename;
+ }
+ return "";
+ }
+ }
+
+ public AnalysisType AnalysisType
+ {
+ get { return analysisType; }
+ set { analysisType = value; }
+ }
+
+ public ProbabilisticType ProbabilisticType
+ {
+ get { return probabilisticType; }
+ set { probabilisticType = value; }
+ }
+
+ [Browsable(false)]
+ public DamFailureMechanismeCalculationSpecification DamFailureMechanismeCalculation
+ {
+ get { return damFailureMechanismeCalculationSpecification; }
+ set { damFailureMechanismeCalculationSpecification = value; }
+ }
+
+ public string ID
+ {
+ get { return this.id; }
+ }
+
+ public string DikeName
+ {
+ get { return dike.Name; }
+ }
+
+ public string Calculation
+ {
+ get { return this.damFailureMechanismeCalculationSpecification != null ? this.damFailureMechanismeCalculationSpecification.ToString() : ""; }
+ }
+
+ public string ScenarioName
+ {
+ get { return this.Scenario.LocationScenarioID; }
+ }
+
+ public string LocationName
+ {
+ get { return this.Scenario.Location.Name; }
+ }
+
+ public int LocationScenarioCount
+ {
+ get { return this.Scenario.Location.Scenarios.Count; }
+ }
+
+ public string ScenarioDefinitionName
+ {
+ get { return this.Scenario.LocationScenarioID + " of " + this.LocationScenarioCount.ToString(); }
+ }
+
+ public CalculationResult CalculationResult
+ {
+ get
+ {
+ return calculationResult;
+ }
+ set
+ {
+ calculationResult = value;
+ }
+ }
+
+ public string ResultMessage
+ {
+ get { return resultMessage; }
+ set { resultMessage = value; }
+ }
+
+ [XmlIgnore]
+ public double X
+ {
+ get
+ {
+ return (this.Scenario != null) ? this.Scenario.Location.XRd : 0.0;
+ }
+ set
+ {
+ if (this.Scenario != null)
+ {
+ this.Scenario.Location.XRd = value;
+ }
+ }
+ }
+
+ [XmlIgnore]
+ public double Y
+ {
+ get
+ {
+ return (this.Scenario != null) ? this.Scenario.Location.YRd : 0.0;
+ }
+ set
+ {
+ if (this.Scenario != null)
+ {
+ this.Scenario.Location.YRd = value;
+ }
+ }
+ }
+
+ public string LocationScenarioId
+ {
+ get { return this.Scenario.LocationScenarioID; }
+ }
+
+ public double? RiverLevel
+ {
+ get { return this.Scenario.RiverLevel; }
+ }
+
+ public double? RiverLevelLow
+ {
+ get { return this.Scenario.RiverLevelLow; }
+ }
+
+ public double? DikeTableHeight
+ {
+ get { return this.Scenario.DikeTableHeight; }
+ }
+
+ public double? SlopeDampingPiezometricHeightPolderSide
+ {
+ get { return this.Scenario.Location.SlopeDampingPiezometricHeightPolderSide; }
+ }
+
+ public double? CurrentDikeHeight
+ {
+ get { return this.Scenario.Location.SurfaceLine2.GetDikeHeight(); }
+ }
+
+ public double? CurrentDikeToeAtPolderX
+ {
+ get
+ {
+ double? x = null;
+ GeometryPoint point = this.Scenario.Location.SurfaceLine2.GetDikeToeInward();
+ if (point != null)
+ x = point.X;
+ return x;
+ }
+ }
+
+ public double? CurrentDikeToeAtPolderZ
+ {
+ get
+ {
+ double? z = null;
+ GeometryPoint point = this.Scenario.Location.SurfaceLine2.GetDikeToeInward();
+ if (point != null)
+ z = point.Z;
+ return z;
+ }
+ }
+
+ private string GetSoilProfileName(FailureMechanismSystemType failureMechanismType)
+ {
+ string soilprofilename = "";
+ if (this.SoilProfile != null)
+ {
+ soilprofilename = this.SoilProfile.Name;
+ }
+ else
+ {
+ if (this.SoilGeometry2DName != null)
+ {
+ soilprofilename = this.SoilGeometry2DName;
+ }
+ }
+ return failureMechanismType == this.damFailureMechanismeCalculationSpecification.FailureMechanismSystemType ? soilprofilename : "";
+ }
+
+ private double? GetSoilProfileProbability(FailureMechanismSystemType? failureMechanismType)
+ {
+ return this.Scenario.Location.GetSoilProfileProbability(this.SoilProfile, failureMechanismType);
+ }
+
+ public string StabilityProfileName
+ {
+ get { return GetSoilProfileName(FailureMechanismSystemType.StabilityInside); }
+ }
+
+ public double? StabilityProfileProbability
+ {
+ get { return GetSoilProfileProbability(FailureMechanismSystemType.StabilityInside); }
+ }
+
+ public string PipingProfileName
+ {
+ get { return GetSoilProfileName(FailureMechanismSystemType.Piping); }
+ }
+
+ public double? PipingProfileProbability
+ {
+ get { return GetSoilProfileProbability(FailureMechanismSystemType.Piping); }
+ }
+
+ public double? CurrentDikeLength
+ {
+ get { return this.Scenario.Location.SurfaceLine2.GetDikeLength(); }
+ }
+
+ public double? StabilityToeAtPolderX
+ {
+ get
+ {
+ if (this.redesignedSurfaceLineStability == null)
+ return null;
+
+ GeometryPoint point = this.redesignedSurfaceLineStability.GetDikeToeInward();
+ if (point != null)
+ return point.X;
+ else
+ return null;
+ }
+ }
+
+ public double? StabilityToeAtPolderZ
+ {
+ get
+ {
+ if (this.redesignedSurfaceLineStability == null)
+ return null;
+
+ GeometryPoint point = this.redesignedSurfaceLineStability.GetDikeToeInward();
+ if (point != null)
+ return point.Z;
+ else
+ return null;
+ }
+ }
+
+ public double? StabilityShoulderHeight
+ {
+ get
+ {
+ if (this.redesignedSurfaceLineStability == null)
+ return null;
+
+ GeometryPoint point = this.redesignedSurfaceLineStability.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside);
+ if (point != null)
+ return point.Z;
+ else
+ return null;
+ }
+ }
+
+ public double? StabilitySafetyFactor
+ {
+ get { return this.safetyFactorStability; }
+ set { this.safetyFactorStability = value; }
+ }
+
+ public double? StabilityFailureProbability
+ {
+ get { return this.failureProbabilityStability; }
+ set { this.failureProbabilityStability = value; }
+ }
+
+ public double? RequiredSafetyFactorStabilityInnerSlope
+ {
+ get { return this.Scenario.RequiredSafetyFactorStabilityInnerSlope;}
+ }
+
+ public double? RequiredSafetyFactorStabilityOuterSlope
+ {
+ get { return this.Scenario.RequiredSafetyFactorStabilityOuterSlope; }
+ }
+
+ public double? RequiredSafetyFactorPiping
+ {
+ get { return this.Scenario.RequiredSafetyFactorPiping; }
+ }
+
+ public double? PipingToeAtPolderX
+ {
+ get
+ {
+ if (this.redesignedSurfaceLinePiping == null)
+ return null;
+
+ GeometryPoint point = this.redesignedSurfaceLinePiping.GetDikeToeInward();
+ if (point != null)
+ return point.X;
+ else
+ return null;
+ }
+ }
+
+ public double? PipingToeAtPolderZ
+ {
+ get
+ {
+ if (this.redesignedSurfaceLinePiping == null)
+ return null;
+
+ GeometryPoint point = this.redesignedSurfaceLinePiping.GetDikeToeInward();
+ if (point != null)
+ return point.Z;
+ else
+ return null;
+ }
+ }
+
+ public double? PipingShoulderHeight
+ {
+ get
+ {
+ if (this.redesignedSurfaceLinePiping == null)
+ return null;
+
+ GeometryPoint point = redesignedSurfaceLinePiping.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside);
+ if (point != null)
+ return point.Z;
+ else
+ return null;
+ }
+ }
+
+ public double? PipingFailureProbability
+ {
+ get { return this.failureProbabilityPiping; }
+ set { this.failureProbabilityPiping = value; }
+ }
+
+ public double? RequiredFailureProbabilityPiping
+ {
+ get { return this.Scenario.RequiredProbabilityOfFailurePiping; }
+ }
+
+ public double? DikeLength
+ {
+ get
+ {
+ double? maxDikeLength = null;
+ List dikeLengths = new List();
+ SurfaceLine2 surfaceLine = this.Scenario.Location.SurfaceLine2;
+ if (surfaceLine != null)
+ dikeLengths.Add(surfaceLine.GetDikeLength());
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ if (redesignedSurfaceLineStability != null)
+ dikeLengths.Add(redesignedSurfaceLineStability.GetDikeLength());
+ break;
+ case FailureMechanismSystemType.Piping:
+ if (redesignedSurfaceLinePiping != null)
+ dikeLengths.Add(redesignedSurfaceLinePiping.GetDikeLength());
+ break;
+ }
+
+ foreach (double? dikeLength in dikeLengths)
+ {
+ if (dikeLength.HasValue && (!maxDikeLength.HasValue || maxDikeLength < dikeLength))
+ maxDikeLength = dikeLength;
+ }
+ return maxDikeLength;
+ }
+ }
+
+ public double? Zone1SafetyFactorStability
+ {
+ get { return this.zone1SafetyFactorStability; }
+ set { this.zone1SafetyFactorStability = value; }
+ }
+
+ public double? LocalZone1EntryPointX
+ {
+ get { return localZone1EntryPointX; }
+ set { localZone1EntryPointX = value; }
+ }
+
+ [XmlIgnore]
+ public double? Zone1EntryPointX
+ {
+ get
+ {
+ if (this.LocalZone1EntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone1EntryPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [XmlIgnore]
+ public double? Zone1EntryPointY
+ {
+ get
+ {
+ if (this.LocalZone1EntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone1EntryPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ [XmlIgnore]
+ public double? Zone1EntryPointZ
+ {
+ get
+ {
+ if (this.LocalZone1EntryPointX == null)
+ return null;
+ if (redesignedSurfaceLineStability == null)
+ return null;
+ return this.redesignedSurfaceLineStability.Geometry.GetZatX(this.LocalZone1EntryPointX.Value);
+ }
+ }
+
+ public double? LocalZone1ExitPointX
+ {
+ get { return localZone1ExitPointX; }
+ set { localZone1ExitPointX = value; }
+ }
+
+ public double? Zone1ExitPointX
+ {
+ get
+ {
+ if (this.LocalZone1ExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone1ExitPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ public double? Zone1ExitPointY
+ {
+ get
+ {
+ if (this.LocalZone1ExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone1ExitPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ public double? Zone1ExitPointZ
+ {
+ get
+ {
+ if (this.LocalZone1ExitPointX == null)
+ return null;
+ if (redesignedSurfaceLineStability == null)
+ return null;
+ return this.redesignedSurfaceLineStability.Geometry.GetZatX(this.LocalZone1ExitPointX.Value);
+ }
+ }
+
+ public double? Zone2SafetyFactorStability
+ {
+ get { return this.zone2SafetyFactorStability; }
+ set { this.zone2SafetyFactorStability = value; }
+ }
+
+ public double? LocalZone2EntryPointX
+ {
+ get { return localZone2EntryPointX; }
+ set { localZone2EntryPointX = value; }
+ }
+
+ public double? Zone2EntryPointX
+ {
+ get
+ {
+ if (this.LocalZone2EntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone2EntryPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+
+ }
+ }
+
+ public double? Zone2EntryPointY
+ {
+ get
+ {
+ if (this.LocalZone2EntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone2EntryPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+
+ }
+ }
+
+ public double? Zone2EntryPointZ
+ {
+ get
+ {
+ if (this.LocalZone2EntryPointX == null)
+ return null;
+ if (redesignedSurfaceLineStability == null)
+ return null;
+ return this.redesignedSurfaceLineStability.Geometry.GetZatX(this.LocalZone2EntryPointX.Value);
+ }
+ }
+
+ public double? LocalZone2ExitPointX
+ {
+ get { return localZone2ExitPointX; }
+ set { localZone2ExitPointX = value; }
+ }
+
+ public double? Zone2ExitPointX
+ {
+ get
+ {
+ if (this.LocalZone2ExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone2ExitPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ public double? Zone2ExitPointY
+ {
+ get
+ {
+ if (this.LocalZone2ExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone2ExitPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ public double? Zone2ExitPointZ
+ {
+ get
+ {
+ if (this.LocalZone2ExitPointX == null)
+ return null;
+ if (redesignedSurfaceLineStability == null)
+ return null;
+ return this.redesignedSurfaceLineStability.Geometry.GetZatX(this.LocalZone2ExitPointX.Value);
+ }
+ }
+
+ public bool? IsUplift
+ {
+ get { return this.isUplift; }
+ set { this.isUplift = value; }
+ }
+
+ public double? Pl3MinUplift
+ {
+ get { return this.pl3MinUplift; }
+ set { this.pl3MinUplift = value; }
+ }
+
+ public double? Pl3HeadAdjusted
+ {
+ get { return this.pl3HeadAdjusted; }
+ set { this.pl3HeadAdjusted = value; }
+ }
+
+ public double? Pl3LocalLocationXMinUplift
+ {
+ get { return this.pl3LocalLocationXMinUplift; }
+ set { this.pl3LocalLocationXMinUplift = value; }
+ }
+
+ [XmlIgnore]
+ public double? Pl3LocationXMinUplift
+ {
+ get
+ {
+ if (this.pl3LocalLocationXMinUplift == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.pl3LocalLocationXMinUplift.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [XmlIgnore]
+ public double? Pl3LocationYMinUplift
+ {
+ get
+ {
+ if (this.pl3LocalLocationXMinUplift == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.pl3LocalLocationXMinUplift.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ public double? Pl4MinUplift
+ {
+ get { return this.pl4MinUplift; }
+ set { this.pl4MinUplift = value; }
+ }
+
+ public double? Pl4HeadAdjusted
+ {
+ get { return this.pl4HeadAdjusted; }
+ set { this.pl4HeadAdjusted = value; }
+ }
+
+ public double? Pl4LocalLocationXMinUplift
+ {
+ get { return this.pl4LocalLocationXMinUplift; }
+ set { this.pl4LocalLocationXMinUplift = value; }
+ }
+
+ [XmlIgnore]
+ public double? Pl4LocationXMinUplift
+ {
+ get
+ {
+ if (this.pl4LocalLocationXMinUplift == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.pl4LocalLocationXMinUplift.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [XmlIgnore]
+ public double? Pl4LocationYMinUplift
+ {
+ get
+ {
+ if (this.pl4LocalLocationXMinUplift == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.pl4LocalLocationXMinUplift.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ public double? UpliftFactor
+ {
+ get { return this.upliftFactor; }
+ set { this.upliftFactor = value; }
+ }
+
+ public double? HeaveFactor
+ {
+ get { return this.heaveFactor; }
+ set { this.heaveFactor = value; }
+ }
+
+ public double? BlighPipingFactor
+ {
+ get { return this.blighPipingFactor; }
+ set { this.blighPipingFactor = value; }
+ }
+
+ public double? BlighHCritical
+ {
+ get { return this.blighHCritical; }
+ set { this.blighHCritical = value; }
+ }
+
+ public double? Sellmeijer2ForcesPipingFactor
+ {
+ get { return this.sellmeijer2ForcesPipingFactor; }
+ set { this.sellmeijer2ForcesPipingFactor = value; }
+ }
+
+ public double? Sellmeijer2ForcesHCritical
+ {
+ get { return this.sellmeijer2ForcesHCritical; }
+ set { this.sellmeijer2ForcesHCritical = value; }
+ }
+
+ public double? Sellmeijer4ForcesPipingFactor
+ {
+ get { return this.sellmeijer4ForcesPipingFactor; }
+ set { this.sellmeijer4ForcesPipingFactor = value; }
+ }
+
+ public double? Sellmeijer4ForcesHCritical
+ {
+ get { return this.sellmeijer4ForcesHCritical; }
+ set { this.sellmeijer4ForcesHCritical = value; }
+ }
+
+ public double? SellmeijerPipingFactor
+ {
+ get { return this.sellmeijerPipingFactor; }
+ set { this.sellmeijerPipingFactor = value; }
+ }
+
+ public double? SellmeijerHCritical
+ {
+ get { return this.sellmeijerHCritical; }
+ set { this.sellmeijerHCritical = value; }
+ }
+
+ ///
+ /// Gets or sets the wti2017 piping factor.
+ ///
+ ///
+ /// The wti2017 piping factor.
+ ///
+ public double? Wti2017PipingFactor
+ {
+ get { return wti2017PipingFactor; }
+ set { wti2017PipingFactor = value; }
+ }
+
+ ///
+ /// Gets or sets the wti2017 h critical.
+ ///
+ ///
+ /// The wti2017 h critical.
+ ///
+ public double? Wti2017HCritical
+ {
+ get { return wti2017HCritical; }
+ set { wti2017HCritical = value; }
+ }
+
+ public string NwoId { get { return this.nwoId; } }
+
+ public int NwoResultIndex
+ {
+ get { return this.nwoResultIndex; }
+ }
+
+ public double? NWOLocationXrdStart
+ {
+ get { return this.locationXrdStart; }
+ }
+
+ public double? NWOLocationYrdStart
+ {
+ get { return this.locationYrdStart; }
+ }
+
+ public double? NWOLocationZrdStart
+ {
+ get { return this.locationZrdStart; }
+ }
+
+ public double? NWOLocationXrdEnd
+ {
+ get { return this.locationXrdEnd; }
+ }
+
+ public double? NWOLocationYrdEnd
+ {
+ get { return this.locationYrdEnd; }
+ }
+
+ public double? NWOLocationZrdEnd { get { return this.locationZrdEnd; } }
+ //Note: using SurfaceLine instead of LocalXzSurfaceLine must give the proper RD coors. If this is not the case, error is somewhere else. Do not convert here!
+
+ public double? DikeToeAtRiverXrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X; }
+ }
+
+ public double? DikeToeAtRiverYrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).Y; }
+ }
+
+ public double? DikeToeAtRiverZrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).Z; }
+ }
+
+ public double? DikeTopAtRiverXrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X; }
+ }
+
+ public double? DikeTopAtRiverYrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Y; }
+ }
+
+ public double? DikeTopAtRiverZrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z; }
+ }
+
+ public double? DikeTopAtPolderXrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X; }
+ }
+
+ public double? DikeTopAtPolderYrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Y; }
+ }
+
+ public double? DikeTopAtPolderZrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z; }
+ }
+
+ public double? DikeToeAtPolderXrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; }
+ }
+
+ public double? DikeToeAtPolderYrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Y; }
+ }
+
+ public double? DikeToeAtPolderZrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; }
+ }
+
+ public double? FlowSlideSafetyFactor
+ {
+ get { return this.safetyFactorFlowSlide; }
+ set { this.safetyFactorFlowSlide = value; }
+ }
+
+ public Scenario Scenario
+ {
+ get { return scenario; }
+ set { scenario = value; }
+ }
+
+ public SoilProfile1D SoilProfile
+ {
+ get { return soilProfile; }
+ set { soilProfile = value; }
+ }
+
+ public string SoilGeometry2DName
+ {
+ get { return soilGeometry2DName; }
+ set { soilGeometry2DName = value; }
+ }
+
+ ///
+ /// Creates a new instance based on
+ /// with global coordinates instead of local coordinates.
+ ///
+ public SurfaceLine2 CreateRedesignedSurfaceLineStabilityGlobal()
+ {
+ if (this.RedesignedSurfaceLine2Stability == null)
+ return null;
+
+ SurfaceLine2 originalSurfaceLine = this.Scenario.Location.SurfaceLine2;
+ var coordinateSystemConverter = new CoordinateSystemConverter();
+ coordinateSystemConverter.DefineGlobalXYZBasedOnLine(originalSurfaceLine.Geometry);
+
+ var redesignedSurfaceLineStabilityGlobal = new SurfaceLine2
+ {
+ CharacteristicPoints = { GeometryMustContainPoint = true },
+ Geometry = new GeometryPointString()
+ };
+ redesignedSurfaceLineStabilityGlobal.Assign(this.RedesignedSurfaceLine2Stability);
+ coordinateSystemConverter.ConvertLocalXZToGlobalXYZ(redesignedSurfaceLineStabilityGlobal.Geometry);
+
+ return redesignedSurfaceLineStabilityGlobal;
+ }
+
+ public SurfaceLine2 RedesignedSurfaceLine2Stability
+ {
+ get { return redesignedSurfaceLineStability; }
+ set { redesignedSurfaceLineStability = value; }
+ }
+
+ ///
+ /// Creates a new instance based on
+ /// with global coordinates instead of local coordinates.
+ ///
+ public SurfaceLine2 CreateRedesignedSurfaceLinePipingGlobal()
+ {
+ if (this.RedesignedSurfaceLine2Piping == null)
+ return null;
+
+ SurfaceLine2 originalSurfaceLine = this.Scenario.Location.SurfaceLine2;
+ var coordinateSystemConverter = new CoordinateSystemConverter();
+ coordinateSystemConverter.DefineGlobalXYZBasedOnLine(originalSurfaceLine.Geometry);
+
+ var redesignedSurfaceLinePipingGlobal = new SurfaceLine2
+ {
+ CharacteristicPoints = { GeometryMustContainPoint = true },
+ Geometry = new GeometryPointString()
+ };
+ redesignedSurfaceLinePipingGlobal.Assign(this.RedesignedSurfaceLine2Piping);
+ coordinateSystemConverter.ConvertLocalXZToGlobalXYZ(redesignedSurfaceLinePipingGlobal.Geometry);
+
+ return redesignedSurfaceLinePipingGlobal;
+ }
+
+ public SurfaceLine2 RedesignedSurfaceLine2Piping
+ {
+ get { return redesignedSurfaceLinePiping; }
+ set { redesignedSurfaceLinePiping = value; }
+ }
+
+ [XmlIgnore]
+ public string ProfileName
+ {
+ get
+ {
+ var res = "";
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.HorizontalBalance:
+ case FailureMechanismSystemType.StabilityOutside:
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilityProfileName;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingProfileName;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public double? ProfileProbability
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.HorizontalBalance:
+ case FailureMechanismSystemType.StabilityOutside:
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilityProfileProbability;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingProfileProbability;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public MStabModelType? StabilityModel
+ {
+ get
+ {
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityOutside:
+ case FailureMechanismSystemType.StabilityInside:
+ return damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.Model;
+ default:
+ return null;
+ }
+ }
+ }
+
+ [XmlIgnore]
+ public double? SafetyFactor
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.HorizontalBalance:
+ case FailureMechanismSystemType.StabilityOutside:
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilitySafetyFactor;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingFactor;
+ break;
+ case FailureMechanismSystemType.FlowSlide:
+ res = FlowSlideSafetyFactor;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public double? FailureProbability
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.HorizontalBalance:
+ case FailureMechanismSystemType.StabilityOutside:
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilityFailureProbability;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingFailureProbability;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public double? RequiredFailureProbability
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.Piping:
+ res = RequiredFailureProbabilityPiping;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public double? RequiredSafetyFactor
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityOutside:
+ res = RequiredSafetyFactorStabilityOuterSlope;
+ break;
+ case FailureMechanismSystemType.StabilityInside:
+ res = RequiredSafetyFactorStabilityInnerSlope;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = RequiredSafetyFactorPiping;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public double? ShoulderHeight
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilityShoulderHeight;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingShoulderHeight;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public double? ToeAtPolderX
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilityToeAtPolderX;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingToeAtPolderX;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public double? ToeAtPolderZ
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilityToeAtPolderZ;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingToeAtPolderZ;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public PipingModelType? PipingModel
+ {
+ get
+ {
+ if (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.Piping)
+ {
+ return damFailureMechanismeCalculationSpecification.PipingModelType;
+ }
+ return null;
+ }
+ }
+
+ [XmlIgnore]
+ public double? PipingFactor
+ {
+ get
+ {
+ double? res = null;
+ if (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.Piping)
+ {
+ switch (damFailureMechanismeCalculationSpecification.PipingModelType)
+ {
+ case PipingModelType.Bligh:
+ res = BlighPipingFactor;
+ break;
+ case PipingModelType.Sellmeijer:
+ res = SellmeijerPipingFactor;
+ break;
+ case PipingModelType.Sellmeijer2Forces:
+ res = Sellmeijer2ForcesPipingFactor;
+ break;
+ case PipingModelType.Sellmeijer4Forces:
+ res = Sellmeijer4ForcesPipingFactor;
+ break;
+ case PipingModelType.Wti2017:
+ res = Wti2017PipingFactor;
+ break;
+ }
+ }
+ return res;
+ }
+ }
+
+ [XmlIgnore]
+ public double? LocalPipingEntryPointX
+ {
+ get
+ {
+ GeometryPoint point = null;
+ if (this.RedesignedSurfaceLine2Piping != null)
+ {
+ point = this.RedesignedSurfaceLine2Piping.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver);
+ }
+ else
+ {
+ point = this.scenario.Location.LocalXZSurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver);
+ }
+ if (point != null)
+ return point.X;
+ else
+ return null;
+ }
+ }
+
+ [XmlIgnore]
+ public double? PipingEntryPointX
+ {
+ get
+ {
+ if (this.LocalPipingEntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalPipingEntryPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [XmlIgnore]
+ public double? PipingEntryPointY
+ {
+ get
+ {
+ if (this.LocalPipingEntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalPipingEntryPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ public double? LocalPipingExitPointX
+ {
+ get { return localPipingExitPointX; }
+ set { localPipingExitPointX = value; }
+ }
+
+ [XmlIgnore]
+ public double? PipingExitPointX
+ {
+ get
+ {
+ if (this.LocalPipingExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalPipingExitPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [XmlIgnore]
+ public double? PipingExitPointY
+ {
+ get
+ {
+ if (this.LocalPipingExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalPipingExitPointX.Value, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ public double? SeepageLength
+ {
+ get { return LocalPipingExitPointX - LocalPipingEntryPointX; }
+ }
+
+ [XmlIgnore]
+ public double? HCritical
+ {
+ get
+ {
+ double? res = null;
+ if (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.Piping)
+ {
+ switch (damFailureMechanismeCalculationSpecification.PipingModelType)
+ {
+ case PipingModelType.Bligh:
+ res = BlighHCritical;
+ break;
+ case PipingModelType.Sellmeijer:
+ res = SellmeijerHCritical;
+ break;
+ case PipingModelType.Sellmeijer2Forces:
+ res = Sellmeijer2ForcesHCritical;
+ break;
+ case PipingModelType.Sellmeijer4Forces:
+ res = Sellmeijer4ForcesHCritical;
+ break;
+ case PipingModelType.Wti2017:
+ res = Wti2017HCritical;
+ break;
+ }
+ }
+ return res;
+ }
+ }
+
+ public string BaseFileName
+ {
+ get { return baseFileName; }
+ set { baseFileName = value; }
+ }
+
+ public string CalculationSubDir
+ {
+ get { return calculationSubDir; }
+ set { calculationSubDir = value; }
+ }
+
+ public ResultEvaluation ResultEvaluation
+ {
+ get { return resultEvaluation; }
+ set
+ {
+ resultEvaluation = value;
+ }
+ }
+
+ public string Notes
+ {
+ get { return notes; }
+ set
+ {
+ notes = value;
+ }
+ }
+
+ ///
+ /// Returns the begin point and end point as a list
+ ///
+ [XmlIgnore]
+ public List Points
+ {
+ get
+ {
+ if (dirty)
+ {
+ dirty = false;
+ points.Clear();
+ if (this.locationXrdStart.HasValue && this.locationYrdStart.HasValue)
+ {
+ points.Add(new GeometryPoint(this.locationXrdStart.Value, this.locationYrdStart.Value));
+ }
+ if (this.locationXrdEnd.HasValue && this.locationYrdEnd.HasValue)
+ {
+ points.Add(new GeometryPoint(this.locationXrdEnd.Value, this.locationYrdEnd.Value));
+ }
+ }
+
+ return points;
+ }
+ }
+
+ ///
+ /// Copy data
+ ///
+ ///
+ public void Assign(CsvExportData csvExportData)
+ {
+ this.id = csvExportData.id;
+ this.BaseFileName = csvExportData.BaseFileName;
+ this.CalculationSubDir = csvExportData.CalculationSubDir;
+ this.NumberOfIterations = csvExportData.NumberOfIterations;
+ this.dike = csvExportData.dike;
+ this.damFailureMechanismeCalculationSpecification = csvExportData.damFailureMechanismeCalculationSpecification;
+ this.Scenario = csvExportData.Scenario;
+ this.SoilProfile = csvExportData.SoilProfile;
+ this.SoilGeometry2DName = csvExportData.SoilGeometry2DName;
+ this.probabilisticType = csvExportData.ProbabilisticType;
+
+ this.failureProbabilityPiping = csvExportData.failureProbabilityPiping;
+ this.redesignedSurfaceLinePiping = csvExportData.redesignedSurfaceLinePiping;
+ this.safetyFactorStability = csvExportData.safetyFactorStability;
+ this.failureProbabilityStability = csvExportData.failureProbabilityStability;
+ this.zone1SafetyFactorStability = csvExportData.zone1SafetyFactorStability;
+ this.LocalZone1EntryPointX = csvExportData.LocalZone1EntryPointX;
+ this.LocalZone1ExitPointX = csvExportData.LocalZone1ExitPointX;
+ this.zone2SafetyFactorStability = csvExportData.zone2SafetyFactorStability;
+ this.LocalZone2EntryPointX = csvExportData.LocalZone2EntryPointX;
+ this.LocalZone2ExitPointX = csvExportData.LocalZone2ExitPointX;
+ this.blighPipingFactor = csvExportData.blighPipingFactor;
+ this.blighHCritical = csvExportData.blighHCritical;
+ this.sellmeijer2ForcesPipingFactor = csvExportData.sellmeijer2ForcesPipingFactor;
+ this.sellmeijer2ForcesHCritical = csvExportData.sellmeijer2ForcesHCritical;
+ this.sellmeijer4ForcesPipingFactor = csvExportData.sellmeijer4ForcesPipingFactor;
+ this.sellmeijer4ForcesHCritical = csvExportData.sellmeijer4ForcesHCritical;
+ this.sellmeijerPipingFactor = csvExportData.sellmeijerPipingFactor;
+ this.sellmeijerHCritical = csvExportData.sellmeijerHCritical;
+ this.wti2017PipingFactor = csvExportData.wti2017PipingFactor;
+ this.wti2017HCritical = csvExportData.wti2017HCritical;
+ this.redesignedSurfaceLineStability = csvExportData.redesignedSurfaceLineStability;
+ this.calculationResult = csvExportData.calculationResult;
+ }
+
+ ///
+ /// Copies the result file.
+ ///
+ /// The extension.
+ private void CopyResultFile(string extension)
+ {
+ string copyResFile = Path.GetDirectoryName(InputFile) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(InputFile) + " (copy)" + extension;
+ var resFile = Path.ChangeExtension(InputFile, extension);
+ File.Copy(resFile, copyResFile, true);
+ }
+
+ private string GetCurrentExeForOpenCalculationFile()
+ {
+ var exeName = DamProjectData.MStabExePath;
+ if (SelectedStabilityKernelType != StabilityKernelType.DamClassic)
+ {
+ exeName = Path.GetDirectoryName(exeName) + "\\MStab.exe";
+ }
+ return exeName;
+ }
+
+ ///
+ /// Opens the calculation file.
+ ///
+ public void OpenCalculationFile()
+ {
+ if (File.Exists(InputFile))
+ {
+ string copyFile = Path.GetDirectoryName(InputFile) + Path.DirectorySeparatorChar +
+ Path.GetFileNameWithoutExtension(InputFile) + " (copy)" + Path.GetExtension(InputFile);
+ File.Copy(InputFile, copyFile, true);
+ var exeName = GetCurrentExeForOpenCalculationFile();
+ if (SelectedStabilityKernelType == StabilityKernelType.DamClassic)
+ {
+ const string stdExtension = ".std";
+ CopyResultFile(stdExtension);
+
+ const string stoExtension = ".sto";
+ CopyResultFile(stoExtension);
+ }
+ Process process = new Process();
+ process.StartInfo.RedirectStandardOutput = false;
+ process.StartInfo.FileName = exeName;
+ if (SelectedStabilityKernelType == StabilityKernelType.DamClassicWti ||
+ SelectedStabilityKernelType == StabilityKernelType.AdvancedWti)
+ {
+ process.StartInfo.Arguments = " -rto " + " \"" + copyFile + "\"";
+ }
+ else
+ {
+ process.StartInfo.Arguments = " \"" + copyFile + "\"";
+ }
+ process.StartInfo.UseShellExecute = false;
+ process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
+ process.Start();
+ }
+ else
+ {
+ if (File.Exists(PipingResultFile))
+ {
+ string copyFile = Path.GetTempPath() + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(PipingResultFile) + " (copy)" +
+ Path.GetExtension(PipingResultFile);
+
+ File.Copy(PipingResultFile, copyFile, true);
+ System.Diagnostics.Process.Start(copyFile);
+ }
+ }
+ }
+
+ ///
+ /// Make a clone of object
+ ///
+ ///
+ public object Clone()
+ {
+ CsvExportData csvExportData = new CsvExportData(this.id, this.dike, this.damFailureMechanismeCalculationSpecification, this.Scenario,
+ this.SoilProfile, this.SoilGeometry2DName, this.analysisType, this.nwoResultIndex, this.probabilisticType);
+
+ csvExportData.Assign(this);
+
+ return csvExportData;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/SoilGeometry2DName.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/SoilGeometry2DName.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/SoilGeometry2DName.cs (revision 334)
@@ -0,0 +1,34 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class SoilGeometry2DName
+ {
+ private string geometry2DName;
+
+ public virtual string Geometry2DName
+ {
+ get { return geometry2DName; }
+ set { geometry2DName = value; }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/DilatancyType.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/DilatancyType.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/DilatancyType.cs (revision 334)
@@ -0,0 +1,44 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Dilatancy (shear thickening) type enumerator
+ ///
+ public enum DilatancyType
+ {
+ ///
+ /// The phi
+ ///
+ Phi = 1,
+
+ ///
+ /// The zero
+ ///
+ Zero = 2,
+
+ ///
+ /// The minus phi
+ ///
+ MinusPhi = 3
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/SchematizationFactor/SchematizationFactorCalculation.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/SchematizationFactor/SchematizationFactorCalculation.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/SchematizationFactor/SchematizationFactorCalculation.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilTypes.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilTypes.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilTypes.cs (revision 334)
@@ -0,0 +1,35 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Enumerator for commonly used major soil types (Sand, Peat, Loam, Clay, Gravel)
+ ///
+ public enum SoilType
+ {
+ Sand,
+ Peat,
+ Loam,
+ Clay,
+ Gravel
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityFileParseException.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityFileParseException.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityFileParseException.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityServiceFileParser.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityServiceFileParser.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityServiceFileParser.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenariosCalculation.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenariosCalculation.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/Dikes Assessment Regional/RWScenariosCalculation.cs (revision 334)
@@ -0,0 +1,627 @@
+// 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.Diagnostics;
+using System.Linq;
+using System.Text.RegularExpressions;
+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;
+
+namespace Deltares.DamEngine.Calculators.Dikes_Assessment_Regional
+{
+ ///
+ /// Exception for RWScenariosCalculation class
+ ///
+ public class RWScenariosCalculationException : ApplicationException
+ {
+ public RWScenariosCalculationException() { }
+ public RWScenariosCalculationException(string message) : base(message) { }
+ }
+
+ public class RWScenariosCalculation : ICalculation
+ {
+ private EvaluationJob evaluationJob = null;
+ private GetValuesDelegate getValuesDelegate = null;
+ private ProgressDelegate progressDelegate = null;
+ private SendMessageDelegate sendMessageDelegate = null;
+ private string mstabExePath = @".\DGeoStability.exe";
+ private int maxCalculationCores = 255;
+
+ private Dictionary runningJobs = new Dictionary();
+ private bool isSkipStabilityCalculation = false;
+ private SchematizationFactorData schematizationFactorData;
+
+ public PipingModelType PipingModelType { get; set; }
+ public MStabParameters MStabParameters { get; set; }
+
+ public RWScenariosCalculation()
+ {
+ }
+
+ #region ICalculation Members
+
+ public CalculationResult GetResults(ref string results)
+ {
+ // 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;
+ // }##Bka
+ return CalculationResult.UnexpectedError;
+ }
+
+ public CalculationResult RegisterGetValues(GetValuesDelegate getValuesDelegate)
+ {
+ this.getValuesDelegate = getValuesDelegate;
+ return CalculationResult.Succeeded;
+ }
+
+ public CalculationResult RegisterProgress(ProgressDelegate progressDelegate)
+ {
+ this.progressDelegate = progressDelegate;
+ return CalculationResult.Succeeded;
+ }
+
+ public CalculationResult RegisterSendDebugInfo(SendDebugInfodelegate sendDebugInfoDelegate)
+ {
+ return CalculationResult.Succeeded;
+ }
+
+ public CalculationResult RegisterSendMessage(SendMessageDelegate sendMessageDelegate)
+ {
+ this.sendMessageDelegate = sendMessageDelegate;
+ return CalculationResult.Succeeded;
+ }
+
+ public CalculationResult RegisterSetValues(SetValuesDelegate setValuesDelegate)
+ {
+ return CalculationResult.Succeeded;
+ }
+
+ public CalculationResult RegisterUserAbort(UserAbortDelegate userAbortDelegate)
+ {
+ return CalculationResult.Succeeded;
+ }
+
+ public CalculationResult Run()
+ {
+ try
+ {
+
+ List tasks = this.FillQueue();
+
+ 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));
+ throw exception;
+ }
+ }
+
+ public CalculationResult Validate()
+ {
+ return CalculationResult.Succeeded;
+ }
+
+ #endregion
+
+ public string Version
+ {
+ get { return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); }
+ }
+
+ public string MStabExePath
+ {
+ get { return mstabExePath; }
+ set { mstabExePath = value; }
+ }
+
+ public bool IsSkipStabilityCalculation
+ {
+ get { return isSkipStabilityCalculation; }
+ set { isSkipStabilityCalculation = value; }
+ }
+
+ public int MaxCalculationCores
+ {
+ get { return maxCalculationCores; }
+ set { maxCalculationCores = value; }
+ }
+
+ public SchematizationFactorData SchematizationFactorData
+ {
+ get { return schematizationFactorData; }
+ set { schematizationFactorData = value; }
+ }
+
+ private List FillQueue()
+ {
+ List tasks = new List();
+
+ this.evaluationJob.FailedEvaluatedLocations = new List();
+ foreach (Location location in this.evaluationJob.Locations)
+ {
+ if (location.Segment == null)
+ {
+ // Add this location to the failed locations
+ if (this.evaluationJob.FailedEvaluatedLocations.IndexOf(location) < 0)
+ {
+ this.evaluationJob.FailedEvaluatedLocations.Add(location);
+ var locationHasNoSegment = LocalizationManager.GetTranslatedText(this.GetType(), "LocationHasNoSegment");
+ sendMessageDelegate(new LogMessage(LogMessageType.Error, location, locationHasNoSegment));
+ }
+ }
+ else
+ {
+ // TODO: Ask Erik Vastenburg how to handle piping and stability soilprofiles when determining RWScenarios
+ // For now we only use the stability profiles.
+ var soilGeometryProbabilities =
+ location.Segment.SoilProfileProbabilities.Where(s => (s.SegmentFailureMechanismType == null) ||
+ (s.SegmentFailureMechanismType.Value ==
+ FailureMechanismSystemType.StabilityInside)).ToList();
+ if (soilGeometryProbabilities.Count == 0)
+ {
+ this.evaluationJob.FailedEvaluatedLocations.Add(location);
+ sendMessageDelegate(
+ new LogMessage(LogMessageType.Warning, location, String.Format("Location has no soilprofiles: ") +
+ String.Format("Segment: {0}", location.Segment.Name)));
+
+ }
+ else
+ {
+ foreach (SoilGeometryProbability soilGeometryProbability in soilGeometryProbabilities)
+ {
+ if (soilGeometryProbability.SoilGeometryType == SoilGeometryType.SoilGeometry2D)
+ {
+ this.evaluationJob.FailedEvaluatedLocations.Add(location);
+ sendMessageDelegate(new LogMessage(LogMessageType.Warning, location, LocalizationManager.GetTranslatedText(this, "Geometry2DNotSupportedInRegionalAssessment") +
+ String.Format("Segment: {0}", location.Segment.Name)));
+ }
+ else
+ {
+
+ SoilProfile soilProfile = soilGeometryProbability.SoilProfile;
+ IList rwScenarios = null;
+ try
+ {
+ rwScenarios = this.GetRWScenarios(location, soilGeometryProbability);
+ }
+ catch (Exception e)
+ {
+ rwScenarios = null;
+ // Add this location to the failed locations
+ if (this.evaluationJob.FailedEvaluatedLocations.IndexOf(location) < 0)
+ {
+ this.evaluationJob.FailedEvaluatedLocations.Add(location);
+ sendMessageDelegate(
+ new LogMessage(LogMessageType.Warning, location, String.Format("Cannot generate scenarios: {0}", e.Message) +
+ String.Format("Soilprofile: {0}", soilProfile.Name)));
+ }
+ }
+ if (rwScenarios != null)
+ {
+ foreach (RWScenarioProfileResult job in rwScenarios)
+ {
+ tasks.Add(job);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return tasks;
+ }
+
+ private IList GetRWScenarios(Location location, SoilGeometryProbability soilGeometryProbability)
+ {
+ RWScenarioSelector selector = new RWScenarioSelector();
+ selector.PipingModelType = PipingModelType;
+ selector.MStabParameters = MStabParameters;
+ return selector.GetScenarios(location, soilGeometryProbability);
+ }
+
+ private void RunTask(object task)
+ {
+ RWScenarioProfileResult job = (RWScenarioProfileResult)task;
+
+ try
+ {
+ if (!IsSkipStabilityCalculation)
+ {
+ ProcessJob(job);
+ }
+ else
+ {
+ job.CalculationResult = CalculationResult.NoRun;
+ }
+ }
+ catch (Exception e)
+ {
+ job.CalculationResult = CalculationResult.UnexpectedError;
+ sendMessageDelegate(new LogMessage(LogMessageType.Warning, job.Location, String.Format("Error: {0}", e.Message)));
+ }
+ }
+
+ ///
+ /// Select which job processor to use, depending on failuremechanism
+ ///
+ ///
+ private void ProcessJob(RWScenarioProfileResult job)
+ {
+ 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));
+ }
+ }
+
+ ///
+ /// Process a job for failuremechanism Piping
+ ///
+ ///
+ 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;
+//
+// 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
+
+ }
+
+ private string GetCalculationNameForPipingCalculator(RWScenarioProfileResult job)
+ {
+ string calculationName;
+ switch (job.PipingModelOption)
+ {
+ case PipingModelType.Sellmeijer : calculationName = String.Format("Calc(Sellmeijer)_Loc({0})_Pro({1}))",
+ job.Location.Name, job.SoilGeometryProbability.SoilProfile.Name);
+ break;
+ case PipingModelType.Sellmeijer2Forces: calculationName = String.Format("Calc(Sellmeijer2Forces)_Loc({0})_Pro({1}))",
+ job.Location.Name, job.SoilGeometryProbability.SoilProfile.Name);
+ break;
+ case PipingModelType.Sellmeijer4Forces: calculationName = String.Format("Calc(Sellmeijer4Forces)_Loc({0})_Pro({1}))",
+ job.Location.Name, job.SoilGeometryProbability.SoilProfile.Name);
+ break;
+ // Set Sellmeijer4Forces as default.
+ default: calculationName = String.Format("Calc(Sellmeijer4Forces)_Loc({0})_Pro({1}))",
+ job.Location.Name, job.SoilGeometryProbability.SoilProfile.Name);
+ break;
+ }
+ calculationName = Regex.Replace(calculationName, @"[\\\/:\*\?""'<>|.]", "_");
+ return calculationName;
+ }
+
+ ///
+ /// Determines the proper calculator for pipng
+ ///
+ ///
+ ///
+ /// 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;
+// }
+
+ ///
+ /// 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);
+// } ##Bka
+ }
+
+ ///
+ /// Log messages
+ ///
+ ///
+ private void SendStabilityMessage(LogMessage logMessage)
+ {
+ lock (runningJobs)
+ {
+ if (logMessage.Subject != null)
+ {
+ RWScenarioProfileResult job = (RWScenarioProfileResult)runningJobs[(ICalculation)logMessage.Subject];
+ logMessage.Subject = job.Location;
+ // logMessage.Detail = job.SoilGeometryProbability.SoilProfile.Name;
+ }
+ }
+
+ this.sendMessageDelegate(logMessage);
+ }
+
+ ///
+ /// Fill the results for the scenarios
+ ///
+ private void FillResults(List tasks)
+ {
+ // Fill scenariosResult structure with jobs just run
+
+ foreach (Location location in this.evaluationJob.Locations)
+ {
+ try
+ {
+ RWScenariosResult scenariosResult = new RWScenariosResult();
+
+ if (this.evaluationJob.FailedEvaluatedLocations.IndexOf(location) < 0)
+ {
+ // scenarios were succesfully created, so results are available
+ foreach (RWScenarioProfileResult job in tasks)
+ {
+ if (job.Location.Name.Equals(location.Name))
+ {
+ RWScenarioResult scenarioResult = null;
+ foreach (RWScenarioResult existingScenarioResult in scenariosResult.RWScenarioResults)
+ {
+ if (existingScenarioResult.ScenarioType == job.ScenarioType)
+ {
+ scenarioResult = existingScenarioResult;
+ }
+ }
+
+ if (scenarioResult == null)
+ {
+ scenarioResult = new RWScenarioResult();
+ scenarioResult.ScenarioType = job.ScenarioType;
+
+ scenariosResult.RWScenarioResults.Add(scenarioResult);
+ }
+
+ scenarioResult.RWScenarioProfileResults.Add(job);
+ }
+ }
+
+ // Combine results
+
+ foreach (RWScenarioResult scenarioResult in scenariosResult.RWScenarioResults)
+ {
+ this.CombineProfiles(scenarioResult);
+ }
+ this.CombineScenarios(scenariosResult);
+
+ }
+ else
+ {
+ // scenarios were not succesfully created, so results are not available
+ // no succesful calculations found
+ scenariosResult.CalculationResult = CalculationResult.RunFailed;
+ scenariosResult.SafetyFactor = double.NaN;
+ }
+
+ if (schematizationFactorData != null)
+ {
+ var results = AddSchematizationFactors(location, scenariosResult);
+ evaluationJob.SchematizationFactorResults.Add(results);
+ }
+ // scenariosResult are the results of all scenarios for one location.
+ this.evaluationJob.Results.Add(scenariosResult);
+
+ }
+ catch (Exception e)
+ {
+ RWScenariosResult scenariosResult = new RWScenariosResult
+ {
+ CalculationResult = CalculationResult.RunFailed,
+ SafetyFactor = double.NaN
+ };
+ sendMessageDelegate(new LogMessage(LogMessageType.Warning, location, String.Format("Error in location {0}: {1}", location.Name, e.Message)));
+ }
+ }
+
+ }
+
+ private RWSchematizationFactorsResult AddSchematizationFactors(Location location, RWScenariosResult scenariosResult)
+ {
+ var schematizationFactorCalculation = new SchematizationFactorCalculation();
+ schematizationFactorCalculation.ScenariosResult = scenariosResult;
+ schematizationFactorCalculation.Location = location;
+ schematizationFactorCalculation.SchematizationFactorData = SchematizationFactorData;
+ schematizationFactorCalculation.DetrimentFactor = location.DetrimentFactor;
+ var results = schematizationFactorCalculation.CalculateSchematizationFactorResults();
+ return results;
+ }
+
+ private void CombineProfiles(RWScenarioResult scenarioResult)
+ {
+ // combine results of profiles
+
+ scenarioResult.SafetyFactor = Double.MaxValue;
+ foreach (RWScenarioProfileResult profileResult in scenarioResult.RWScenarioProfileResults)
+ {
+ if (profileResult.CalculationResult == CalculationResult.Succeeded)
+ {
+ if (profileResult.SafetyFactor < scenarioResult.SafetyFactor)
+ {
+ scenarioResult.SafetyFactor = profileResult.SafetyFactor;
+ }
+
+ scenarioResult.CalculationResult = CalculationResult.Succeeded;
+ }
+ }
+ if (scenarioResult.CalculationResult != CalculationResult.Succeeded)
+ {
+ // no succesful calculations found
+ scenarioResult.CalculationResult = scenarioResult.RWScenarioProfileResults[0].CalculationResult;
+ scenarioResult.SafetyFactor = scenarioResult.RWScenarioProfileResults[0].SafetyFactor;
+ }
+ }
+
+ private void CombineScenarios(RWScenariosResult scenariosResult)
+ {
+ // combine results of scenarios
+ scenariosResult.SafetyFactor = Double.MaxValue;
+ foreach (RWScenarioResult scenarioResult in scenariosResult.RWScenarioResults)
+ {
+ if (scenarioResult.CalculationResult == CalculationResult.Succeeded)
+ {
+ if (scenarioResult.SafetyFactor < scenariosResult.SafetyFactor)
+ {
+ scenariosResult.SafetyFactor = scenarioResult.SafetyFactor;
+ }
+ scenariosResult.CalculationResult = CalculationResult.Succeeded;
+ }
+ }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/DamFailureMechanismeCalculationSpecification.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/DamFailureMechanismeCalculationSpecification.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/DamFailureMechanismeCalculationSpecification.cs (revision 334)
@@ -0,0 +1,233 @@
+// 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.Xml.Serialization;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.General
+{
+ ///
+ ///
+ ///
+ public class DamFailureMechanismeCalculationSpecification
+ {
+ private FailureMechanismSystemType failureMechanismSystemType;
+ private PipingModelType pipingModelType = PipingModelType.Sellmeijer4Forces;
+ private Enum calculationModel;
+ private FailureMechanismeParamatersMStab failureMechanismeParamatersMStab;
+ private static ProbabilisticType probabilisticType;
+ private static DamProjectType damProjectType;
+ private StabilityKernelType stabilityKernelType = StabilityKernelType.DamClassic;
+
+ public DamFailureMechanismeCalculationSpecification()
+ {
+ //Todo interface
+ failureMechanismSystemType = FailureMechanismSystemType.StabilityInside;
+ failureMechanismeParamatersMStab = new FailureMechanismeParamatersMStab();
+ CalculationModel = failureMechanismeParamatersMStab.MStabParameters.Model;
+ FailureMechanismeParamatersMStab.MStabParameters.GridPosition = MStabGridPosition.Right;
+ ReadUserSettingsSlipCircleDefinition();
+ }
+
+ [Validate]
+ public FailureMechanismeParamatersMStab FailureMechanismeParamatersMStab
+ {
+ get { return failureMechanismeParamatersMStab; }
+ set { failureMechanismeParamatersMStab = value; }
+ }
+
+ public FailureMechanismSystemType FailureMechanismSystemType
+ {
+ get { return failureMechanismSystemType; }
+ set
+ {
+ if (failureMechanismSystemType != value)
+ {
+ failureMechanismSystemType = value;
+ // To solve MWDAM-592, remember the current pipingmodeltype as this gets reset by setting the
+ // calculationmodel. Only switch it back when needed.
+ var oldPipingModelType = pipingModelType;
+// foreach (Enum possibleModel in this.GetDomain("CalculationModel"))
+// {
+// this.CalculationModel = possibleModel;
+// break;
+// } #Bka: I think this is only needed for the UI.
+ switch (failureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ failureMechanismeParamatersMStab.MStabParameters.GridPosition = MStabGridPosition.Right;
+ break;
+ case FailureMechanismSystemType.StabilityOutside:
+ failureMechanismeParamatersMStab.MStabParameters.GridPosition = MStabGridPosition.Left;
+ break;
+ case FailureMechanismSystemType.Piping:
+ PipingModelType = oldPipingModelType;
+ break;
+ }
+ }
+ }
+ }
+
+
+ public PipingModelType PipingModelType
+ {
+ get { return pipingModelType; }
+ set
+ {
+ pipingModelType = value;
+ if (failureMechanismSystemType == FailureMechanismSystemType.Piping)
+ {
+ CalculationModel = pipingModelType;
+ }
+ }
+ }
+
+ public static DamProjectType DamProjectType
+ {
+ get { return damProjectType; }
+ set { damProjectType = value; }
+ }
+
+ public static ProbabilisticType ProbabilisticType
+ {
+ get { return probabilisticType; }
+ set { probabilisticType = value; }
+ }
+
+ ///
+ /// The calculationmodel is only needed to support the selection of the modeltype in the UI. The dropdownlist
+ /// in the UI depends on this. This set can be filled with any proper types (for piping, stabilty etc) for any
+ /// mechanisme instead of the fixed types per mechanisme.
+ ///
+ [XmlIgnore]
+ public Enum CalculationModel
+ {
+ get { return calculationModel; }
+ set
+ {
+ calculationModel = value;
+ if (value is PipingModelType)
+ {
+ pipingModelType = (PipingModelType) value;
+ }
+ else
+ {
+ failureMechanismeParamatersMStab.MStabParameters.Model = (MStabModelType)value;
+ }
+ }
+ }
+
+ public MStabModelType StabilityModelType
+ {
+ get { return failureMechanismeParamatersMStab.MStabParameters.Model; }
+ set
+ {
+ failureMechanismeParamatersMStab.MStabParameters.Model = value;
+ if (failureMechanismSystemType != FailureMechanismSystemType.Piping)
+ {
+ CalculationModel = value;
+ }
+ }
+ }
+
+ public StabilityKernelType StabilityKernelType
+ {
+ get { return stabilityKernelType; }
+ set { stabilityKernelType = value; }
+ }
+
+ public void Assign(DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculation)
+ {
+ this.FailureMechanismSystemType = damFailureMechanismeCalculation.failureMechanismSystemType;
+ this.FailureMechanismeParamatersMStab.Assign(damFailureMechanismeCalculation.FailureMechanismeParamatersMStab);
+ //assign interface
+ }
+
+ public DamFailureMechanismeCalculationSpecification Clone()
+ {
+ DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculation = new DamFailureMechanismeCalculationSpecification();
+
+ damFailureMechanismeCalculation.Assign(this);
+
+ return damFailureMechanismeCalculation;
+ }
+
+ public override string ToString()
+ {
+ string description = "";
+ description += String.Format("{0}", StabilityKernelType);
+ description += String.Format("{0}", this.FailureMechanismSystemType);
+ if ((this.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) ||
+ (this.FailureMechanismSystemType == FailureMechanismSystemType.StabilityOutside))
+ {
+ //interface?
+ description += String.Format(" ({0})", this.FailureMechanismeParamatersMStab.MStabParameters.Model);
+ }
+
+ return description;
+ }
+
+ ///
+ /// Determines whether slip circle definition is undefined.
+ ///
+ ///
+ /// true if [is slip circle definition undefined]; otherwise, false.
+ ///
+ public bool IsSlipCircleDefinitionUndefined()
+ {
+ bool isSlipCircleDefinitionUndefined = (failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition == null);
+ if (!isSlipCircleDefinitionUndefined)
+ {
+ isSlipCircleDefinitionUndefined = (failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.UpliftVanLeftGridHorizontalPointCount == 0);
+ }
+ return isSlipCircleDefinitionUndefined;
+ }
+
+ ///
+ /// Reads the user settings.
+ ///
+ 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;
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/ModelFactors.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/ModelFactors.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/ModelFactors.cs (revision 334)
@@ -0,0 +1,56 @@
+// 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.Xml.Serialization;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class ModelFactors
+ {
+ public virtual double? RequiredSafetyFactorStabilityInnerSlope { get; set; }
+ public virtual double? RequiredSafetyFactorStabilityOuterSlope { get; set; }
+ public virtual double? RequiredSafetyFactorPiping { get; set; }
+ public virtual double? RequiredProbabilityOfFailureStabilityInnerslope { get; set; }
+ public virtual double? RequiredProbabilityOfFailureStabilityOuterslope { get; set; }
+ public virtual double? RequiredProbabilityOfFailurePiping { get; set; }
+ public virtual double? UpliftCriterionPiping { get; set; }
+ public virtual double? UpliftCriterionStability { get; set; }
+
+ [XmlIgnore]
+ public double?[] AllValues
+ {
+ get
+ {
+ return new []
+ {
+ RequiredSafetyFactorStabilityInnerSlope,
+ RequiredSafetyFactorStabilityOuterSlope,
+ RequiredSafetyFactorPiping,
+ RequiredProbabilityOfFailureStabilityInnerslope,
+ RequiredProbabilityOfFailureStabilityOuterslope,
+ RequiredProbabilityOfFailurePiping,
+ UpliftCriterionPiping,
+ UpliftCriterionStability
+ };
+ }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs (revision 334)
@@ -0,0 +1,188 @@
+// 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.Collections.Generic;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Standard.Language;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// 2D Soil Profile Object
+ ///
+ public class SoilProfile2D : SoilProfile
+ {
+ protected readonly Dictionary cachedSoilProfiles1D = new Dictionary();
+ protected GeometryData geometry = new GeometryData();
+ protected readonly List surfaces = new List();
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SoilProfile2D()
+ {
+ Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSoilProfile2D");
+ }
+
+ ///
+ /// Gets the surfaces.
+ ///
+ ///
+ /// The surfaces.
+ ///
+ [Validate]
+ public virtual IList Surfaces
+ {
+ get
+ {
+ return surfaces;
+ }
+ }
+
+ ///
+ /// Gets or sets the geometry.
+ ///
+ ///
+ /// The geometry.
+ ///
+ public GeometryData Geometry
+ {
+ get
+ {
+ return geometry;
+ }
+ set
+ {
+ geometry = value;
+ }
+ }
+
+ ///
+ /// Gets the soil profile 1D at the given X.
+ ///
+ /// The x.
+ /// Soil Profile 1D
+ public virtual SoilProfile1D GetSoilProfile1D(double x)
+ {
+ const double diff = 0.001;
+ SoilProfile1D soilProfile = GetCachedSoilProfile1D(x);
+
+ if (soilProfile != null)
+ {
+ return soilProfile;
+ }
+
+ soilProfile = new SoilProfile1D
+ {
+ Name = "Generated at x = " + x + " from " + Name
+ };
+ var detector = new LayerDetector(Surfaces);
+ if (x > Geometry.Right)
+ {
+ x = Geometry.Right - diff;
+ }
+ if (x < Geometry.Left)
+ {
+ x = Geometry.Left + diff;
+ }
+
+ detector.DetermineMaterials(x);
+
+ if (detector.LayerList.Count > 0)
+ {
+ soilProfile.BottomLevel = detector.LayerList[detector.LayerList.Count - 1].EndPoint.Z;
+ for (int i = 0; i < detector.LayerList.Count; i++)
+ {
+ var layer = new SoilLayer1D(detector.LayerList[i].Soil, detector.LayerList[i].StartPoint.Z)
+ {
+ IsAquifer = detector.LayerList[i].IsAquifer
+ };
+ soilProfile.Layers.Add(layer);
+ }
+ }
+
+
+ cachedSoilProfiles1D[x] = soilProfile;
+
+ return soilProfile;
+ }
+
+ ///
+ /// Get the surface from the point
+ ///
+ /// The point which is supposed to be within the soil layer
+ /// Surface
+ public SoilLayer2D GetSoilLayer(Point2D point)
+ {
+ for (int i = 0; i < Surfaces.Count; i++)
+ {
+ SoilLayer2D surface = Surfaces[i];
+ GeometryLoop surfaceLine = surface.GeometrySurface.OuterLoop;
+ if (surfaceLine.IsPointInLoopArea(point))
+ {
+ bool found = true;
+
+ // if point lies in an innerloop it belongs to another area
+ foreach (var innerloop in surface.GeometrySurface.InnerLoops)
+ {
+ if (innerloop.IsPointInLoopArea(point))
+ {
+ found = false;
+ }
+ }
+
+ if (found)
+ {
+ return surface;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ ///
+ /// Gets the cached soil profile1 d.
+ ///
+ /// The x.
+ ///
+ protected SoilProfile1D GetCachedSoilProfile1D(double x)
+ {
+ if (cachedSoilProfiles1D.ContainsKey(x))
+ {
+ return cachedSoilProfiles1D[x];
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs (revision 334)
@@ -0,0 +1,2019 @@
+// 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.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Xml.Linq;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Calculators.Dikes_Design;
+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
+{
+ public class MaximumRedesignIterationsReachedException : Exception
+ {
+ public MaximumRedesignIterationsReachedException() : base("Maximum number of iterations in redesign reached.")
+ {
+ }
+ }
+
+ ///
+ ///
+ ///
+ public class DamFailureMechanismeCalculator
+ {
+ private const int PipingRedesingMaxIterations = 400;
+ private const double defaultMaxFractionOfDikeHeightForShoulderHeight = 0.67;
+ private const double CMinimumShoulderElevation = 0.5;
+ private const double CMinimumShoulderExtraElevation = 0.05;
+ private const double CMinimumShoulderWidth = 2;
+ private const double CMinimumShoulderExtraWidth = 1;
+ private const double CToleranceShoulderChanges = 0.001;
+
+ private readonly DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification;
+ private readonly string mstabProgramPath;
+ private readonly ProgramType programType;
+ private readonly string slopeWProgramPath;
+ private AnalysisType analysisType;
+ private List errorMessages = new List();
+ private int progressSofar;
+
+ public DamFailureMechanismeCalculator(ProgramType programType, DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification,
+ string mstabProgramPath, string slopeWProgramPath, string mapForSoilGeometries2D, ProbabilisticType probabilisticType)
+ {
+ this.programType = programType;
+ this.damFailureMechanismeCalculationSpecification = damFailureMechanismeCalculationSpecification;
+ this.mstabProgramPath = mstabProgramPath;
+ this.slopeWProgramPath = slopeWProgramPath;
+ MapForSoilGeometries2D = mapForSoilGeometries2D;
+ ProbabilisticType = probabilisticType;
+ }
+
+ public string CalculationBaseDirectory { get; set; }
+ public string MapForSoilGeometries2D { get; set; }
+ public ProbabilisticType ProbabilisticType { get; set; }
+ public NonWaterRetainingObject NonWaterRetainingObject { get; set; }
+
+ public List ErrorMessages
+ {
+ get
+ {
+ return errorMessages;
+ }
+ set
+ {
+ errorMessages = value;
+ }
+ }
+
+ ///
+ /// Main calculation call
+ ///
+ ///
+ ///
+ public void Calculate(AnalysisType analysisTypeGiven, Scenario scenario)
+ {
+ Debug.WriteLine("Location '{0}', scenario '{1}' DamFailureMechanismeCalculator.Calculation", scenario.Location.Name, scenario.LocationScenarioID);
+ analysisType = analysisTypeGiven;
+
+ switch (analysisType)
+ {
+ case AnalysisType.NoAdaption:
+ CalculateForScenario(scenario);
+ break;
+
+ case AnalysisType.AdaptGeometry:
+ RedesignSurfaceLinesForAllScenarios(scenario);
+ break;
+ case AnalysisType.AdaptNWO:
+ ImplementNWOInSurfaceLinesForAllScenarios(scenario);
+ break;
+ }
+ }
+
+ ///
+ /// Selects the probabilities for specific failure mechanism.
+ ///
+ /// Type of the failure mechanism system.
+ /// The soil profile probabilities.
+ ///
+ public static List SelectProbabilitiesForFailureMechanism(FailureMechanismSystemType failureMechanismSystemType, IList soilProfileProbabilities)
+ {
+ switch (failureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ case FailureMechanismSystemType.StabilityOutside:
+ case FailureMechanismSystemType.HorizontalBalance:
+ return SelectStabilityProbabilities(soilProfileProbabilities);
+ case FailureMechanismSystemType.Piping:
+ return SelectPipingProbabilities(soilProfileProbabilities);
+ case FailureMechanismSystemType.FlowSlide:
+ return SelectFlowSlideProbabilities(soilProfileProbabilities);
+ }
+ return null;
+ }
+
+ ///
+ /// Redesigns the height of the surface line.
+ ///
+ /// Type of the failure mechanism system.
+ /// The scenario.
+ /// The surface line.
+ ///
+ public static SurfaceLine2 RedesignSurfaceLineHeight(FailureMechanismSystemType failureMechanismSystemType, Scenario scenario, SurfaceLine2 surfaceLine)
+ {
+ double? dikeHeight = surfaceLine.GetDikeHeight();
+ if (dikeHeight.HasValue)
+ {
+ if (scenario.DikeTableHeight > dikeHeight.Value)
+ {
+ var surfaceLineHeightAdapter = new SurfaceLineHeightAdapter(surfaceLine, scenario.Location);
+ SurfaceLine2 adaptedSurfaceLine = surfaceLineHeightAdapter.ConstructNewSurfaceLine(scenario.DikeTableHeight ?? surfaceLine.GetDefaultDikeTableHeight() ?? 0);
+
+ if (adaptedSurfaceLine != null)
+ {
+ var validationError = adaptedSurfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error);
+ if (validationError != null)
+ {
+ throw new SurfaceLineException(validationError.Text);
+ }
+
+ surfaceLine = adaptedSurfaceLine;
+ foreach (var soilProfileProbability in scenario.Location.Segment.SoilProfileProbabilities)
+ {
+ if (soilProfileProbability.SegmentFailureMechanismType == failureMechanismSystemType || soilProfileProbability.SegmentFailureMechanismType == null)
+ {
+ scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile, soilProfileProbability.SoilGeometry2DName, surfaceLine);
+ }
+ }
+ }
+ }
+ }
+ return surfaceLine;
+ }
+
+ ///
+ /// Cleanup directory where the piping project files are created
+ ///
+ public static void ClearPipingCalculationBaseDirectory()
+ {
+ string pipingBaseDirectory = GetPipingCalculationBaseDirectory();
+ if (Directory.Exists(pipingBaseDirectory))
+ {
+ Directory.Delete(pipingBaseDirectory, true);
+ }
+ }
+
+ 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;
+// }
+ }
+
+ ///
+ /// Checks the and adapt betas water levels when needed.
+ ///
+ /// The betas.
+ /// The water levels.
+ /// The scenario.
+ /// The new surface line.
+ /// 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;
+// }
+// }
+//
+// // 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;
+// }
+// }
+
+ // 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;
+// }
+// }
+// }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+// 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;
+//
+// 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);
+//
+// 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;
+// }
+
+ ///
+ /// 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);
+// }
+
+ ///
+ /// Selects the soilProfileProbabilities for piping.
+ ///
+ /// The soil profile probabilities.
+ ///
+ private static List SelectPipingProbabilities(IList soilProfileProbabilities)
+ {
+ var validSoilProfileProbabilities =
+ new List(soilProfileProbabilities.Where(
+ p => ((p.SegmentFailureMechanismType == FailureMechanismSystemType.Piping) ||
+ (p.SegmentFailureMechanismType == null))));
+ return validSoilProfileProbabilities;
+ }
+
+ ///
+ /// Selects the soilProfileProbabilities for stability.
+ ///
+ /// The soil profile probabilities.
+ ///
+ private static List SelectStabilityProbabilities(IList soilProfileProbabilities)
+ {
+ var validSoilProfileProbabilities = new List(soilProfileProbabilities.Where(
+ p => ((p.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityInside) ||
+ (p.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityOutside) ||
+ (p.SegmentFailureMechanismType == null))));
+ return validSoilProfileProbabilities;
+ }
+
+ ///
+ /// Selects the flowslide probabilities.
+ ///
+ /// The soil profile probabilities.
+ ///
+ private static List SelectFlowSlideProbabilities(IList soilProfileProbabilities)
+ {
+ // For now use the stability probabilities
+ return SelectStabilityProbabilities(soilProfileProbabilities);
+ }
+
+ ///
+ /// Consistency check to be performed before stability calculation
+ ///
+ ///
+ private void ConsistencyCheckStability(Scenario scenario)
+ {
+ ConsistencyCheckStabilityPerScenario(scenario);
+ }
+
+ private void ConsistencyCheckStabilityPerScenario(Scenario scenario)
+ {
+ // If outward stability calculation then low waterlevel is required
+ if (damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.GridPosition == MStabGridPosition.Left)
+ {
+ if (!scenario.RiverLevelLow.HasValue)
+ {
+ throw new DamFailureMechanismeCalculatorException(String.Format(
+ "Location {0} scenario {1} has no low waterlevel defined, which is required for outward stability calculation (grid at left).",
+ scenario.Location.Name, scenario.LocationScenarioID));
+ }
+ }
+ }
+
+ ///
+ /// 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;
+//
+// 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)
+ ///
+ /// The uplift situation.
+ ///
+ /// true if [is calculation required] ; otherwise, false.
+ ///
+ private bool IsCalculationRequired(UpliftSituation? upliftSituation)
+ {
+ bool isUplift = upliftSituation.HasValue && upliftSituation.Value.IsUplift;
+ bool isSkipCalculation = (!isUplift &&
+ damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.IsStabilityCheckOnUplift &&
+ (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) &&
+ (damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.UpliftVan));
+ return !isSkipCalculation;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ 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;
+// }
+// }
+ }
+
+// 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;
+// }
+// }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+// 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;
+// }
+
+ ///
+ ///
+ ///
+ ///
+ 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;
+// }
+// }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+// 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;
+// }
+// }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+// 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);
+// }
+// }
+// }
+
+// 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.
+ ///
+ ///
+ ///
+ private IEnumerable GetCheckedSurfaceLine(IEnumerable originalLine)
+ {
+ const double cDiff = 0.5;
+ var newLine = new List();
+ double X = originalLine.First().X;
+ foreach (var point in originalLine)
+ {
+ while (point.X > X + cDiff)
+ {
+ var newPoint = new GeometryPoint(point)
+ {
+ X = X + cDiff
+ };
+ if (newPoint.X > newLine.Last().X)
+ {
+ newPoint.Z = newLine.Last().Z + ((newPoint.X - newLine.Last().X)/(point.X - newLine.Last().X))*
+ (point.Z - newLine.Last().Z);
+ newLine.Add(newPoint);
+ }
+ X = newPoint.X;
+ }
+ newLine.Add(point);
+ }
+ 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;
+//
+// 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
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+// 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.");
+// }
+// }
+
+ ///
+ /// 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;
+// }
+// }
+// }
+// }
+// }
+// }
+
+ ///
+ /// Redesign for Stability:
+ /// Dependent on the exit point of the stability circle.
+ /// If the exit point is in the slope, the slope will be adapted.
+ /// If the exit point is not in the slope, a shoulder will be made,
+ /// or if the shoulder exists, the shoulder will be enlarged.
+ ///
+ ///
+ ///
+ ///
+ ///
+// 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);
+// }
+// }
+
+ ///
+ /// Determines the new height and width of the shoulder width
+ ///
+ /// The shoulder grow delta X.
+ /// The shoulder grow slope.
+ /// The surface line.
+ /// 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
+// };
+//
+// // 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)
+ /// * slope adaption is done in a range between startCoTangent and endCoTangent in steps of stepCoTangent
+ /// * and while the exit point of the slipcircle is in the slope (so currentCoTangent could be larger than endCoTangent
+ /// - than (if required safety is not reached) do shoulder adaption
+ /// Note: Use same slope for shoulder as for dike.
+ ///
+ ///
+ ///
+ ///
+ ///
+// 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);
+// }
+// }
+
+ ///
+ /// Redesigns the surface line flow slide.
+ ///
+ /// The scenario.
+ /// The safety factor.
+ /// The surface line.
+ private void RedesignSurfaceLineFlowSlide(Scenario scenario, double? safetyFactor, ref SurfaceLine2 surfaceLine)
+ {
+ throw new DamFailureMechanismeCalculatorException("Geometry adaption not supported for Flowslide");
+ }
+
+ ///
+ /// Check if a stability redesign is required
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private bool IsRedesignRequired(double? safetyFactor, double requiredSafetyFactor, double betaRequired, double? beta)
+ {
+ bool isRedesignRequired;
+ if (ProbabilisticType == ProbabilisticType.ProbabilisticFragility)
+ {
+ isRedesignRequired = beta > betaRequired;
+ }
+ else
+ {
+ isRedesignRequired = safetyFactor < requiredSafetyFactor;
+ }
+ return isRedesignRequired;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+// 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(DamProjectData.ProjectMap, Path.Combine(MapForSoilGeometries2D, soilGeometry2DName));
+// return fullSoilGeometry2DName;
+// }
+// }
+
+ ///
+ /// Get the directory where to create the piping project files
+ ///
+ ///
+ private static string GetPipingCalculationBaseDirectory()
+ {
+ return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "PipingCalculation\\");
+ }
+
+ ///
+ /// Calculates the maximum level for the shoulder.
+ ///
+ /// The surface line.
+ /// The fraction of dike height to determine maximimum shoulder height.
+ ///
+ private double CalculateMaximumShoulderLevel(SurfaceLine2 surfaceLine, double maxFractionOfDikeHeightForShoulderHeight)
+ {
+ var top = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z;
+ var bottom = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z;
+ if (top - bottom <= 0)
+ {
+ throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineShoulderAdapterMaxShoulderHeightError"));
+ }
+ double maxHeight = Math.Abs((top - bottom)*maxFractionOfDikeHeightForShoulderHeight);
+ return bottom + maxHeight;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointType.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointType.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointType.cs (revision 334)
@@ -0,0 +1,120 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// All types of characteristic points for a surface line.
+ ///
+ ///
+ public enum CharacteristicPointType
+ {
+ ///
+ /// The none
+ ///
+ None,
+
+ ///
+ /// The surface level outside
+ ///
+ SurfaceLevelOutside = 1, // Maaiveld buitenwaarts
+
+ ///
+ /// The dike toe at river
+ ///
+ DikeToeAtRiver = 5, // Teen dijk buitenwaarts
+
+ ///
+ /// The shoulder top outside
+ ///
+ ShoulderTopOutside = 6, // Kruin buitenberm
+
+ ///
+ /// The shoulder base outside
+ ///
+ ShoulderBaseOutside = 7, // Insteek buitenberm
+
+ ///
+ /// The dike top at river
+ ///
+ DikeTopAtRiver = 8, // Kruin buitentalud
+
+ ///
+ /// The dike line
+ ///
+ DikeLine = 9, // referentielijn
+
+ ///
+ /// The traffic load outside
+ ///
+ TrafficLoadOutside = 10, // Verkeersbelasting kant buitenwaarts
+
+ ///
+ /// The traffic load inside
+ ///
+ TrafficLoadInside = 11, // Verkeersbelasting kant binnenwaarts
+
+ ///
+ /// The dike top at polder
+ ///
+ DikeTopAtPolder = 12, // Kruin binnentalud
+
+ ///
+ /// The shoulder base inside
+ ///
+ ShoulderBaseInside = 13, // Insteek binnenberm
+
+ ///
+ /// The shoulder top inside
+ ///
+ ShoulderTopInside = 14, // Kruin binnenberm
+
+ ///
+ /// The dike toe at polder
+ ///
+ DikeToeAtPolder = 15, // Teen dijk binnenwaarts
+
+ ///
+ /// The ditch dike side
+ ///
+ DitchDikeSide = 16, // Insteek sloot dijkzijde
+
+ ///
+ /// The bottom ditch dike side
+ ///
+ BottomDitchDikeSide = 17, // Slootbodem dijkzijde
+
+ ///
+ /// The bottom ditch polder side
+ ///
+ BottomDitchPolderSide = 18, // Slootbodem polderzijde
+
+ ///
+ /// The ditch polder side
+ ///
+ DitchPolderSide = 19, // Insteek sloot polderzijde
+
+ ///
+ /// The surface level inside
+ ///
+ SurfaceLevelInside = 25, // Maaiveld binnenwaarts
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2.cs (revision 334)
@@ -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.Geometry;
+using Deltares.DamEngine.Data.Standard.Language;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Representation of a surface line with characteristic point annotations.
+ ///
+ /// Extension methods can be found in .
+ public class SurfaceLine2 : GeometryObject
+ {
+ private CharacteristicPointSet characteristicPoints;
+ private GeometryPointString geometry;
+
+ ///
+ /// Create a new empty surface line.
+ ///
+ public SurfaceLine2()
+ {
+ geometry = new GeometryPointString();
+ characteristicPoints = new CharacteristicPointSet
+ {
+ GeometryMustContainPoint = true
+ };
+ LandwardDirection = LandwardDirection.PositiveX;
+ Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSurfaceLine2");
+ }
+
+ ///
+ /// The geometrical description of the surface line.
+ ///
+ /// Aggregation relationship.
+ public GeometryPointString Geometry
+ {
+ get
+ {
+ return geometry;
+ }
+ set
+ {
+ geometry = value;
+ CharacteristicPoints.Geometry = geometry;
+ }
+ }
+
+ ///
+ /// The characteristic point annotations for .
+ ///
+ /// Cannot be null.
+ public CharacteristicPointSet CharacteristicPoints
+ {
+ get
+ {
+ return characteristicPoints;
+ }
+ set
+ {
+ characteristicPoints = value;
+ characteristicPoints.Geometry = geometry;
+ }
+ }
+
+ ///
+ /// Determines toward which direction land is expected. Value is used as reference.
+ ///
+ public LandwardDirection LandwardDirection { get; set; }
+
+ ///
+ /// Define a new characteristic point on the surface line with the given characteristic
+ /// point annotation.
+ ///
+ /// The point to be added. Cannot be null.
+ /// The annotations for .
+ public void AddCharacteristicPoint(GeometryPoint geometryPoint, params CharacteristicPointType[] annotations)
+ {
+ if (annotations == null || annotations.Length == 0)
+ {
+ CharacteristicPoints.Add(new CharacteristicPoint
+ {
+ GeometryPoint = geometryPoint,
+ CharacteristicPointType = CharacteristicPointType.None
+ });
+ }
+ else
+ {
+ foreach (var type in annotations)
+ {
+
+ CharacteristicPoints.Add(new CharacteristicPoint
+ {
+ GeometryPoint = geometryPoint,
+ CharacteristicPointType = type
+ });
+ }
+ }
+ }
+
+ ///
+ /// Define a new characteristic point on the surface line with the given characteristic
+ /// point annotation.
+ ///
+ /// The x.
+ /// The y.
+ /// The annotations for geometryPoint with x, z/>.
+ public void AddCharacteristicPoint(double x, double z, params CharacteristicPointType[] annotations)
+ {
+ GeometryPoint geometryPoint = new GeometryPoint(x, z);
+ AddCharacteristicPoint(geometryPoint, annotations);
+ }
+
+ ///
+ /// Find all characteristic point annotations corresponding with the given location.
+ ///
+ ///
+ ///
+ public IEnumerable GetCharacteristicPoints(GeometryPoint geometryPoint)
+ {
+ return CharacteristicPoints.Where(cp => ReferenceEquals(cp.GeometryPoint, geometryPoint))
+ .Select(cp => cp.CharacteristicPointType);
+ }
+
+ ///
+ /// Sort all points on X in a ascending manner.
+ ///
+ public void SortPoints()
+ {
+ CharacteristicPoints.Sort();
+ }
+
+ ///
+ /// Validates this surfaceline.
+ ///
+ /// All validation messages.
+ [Validate]
+ public ValidationResult[] Validate()
+ {
+ return new SurfaceLine2Validator().Validate(this).ToArray();
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ ///
+ /// Gets the geometry bounds (i.e. the extents for drawing)
+ ///
+ ///
+ public override GeometryBounds GetGeometryBounds()
+ {
+ if (CharacteristicPoints.Geometry != null)
+ {
+ return CharacteristicPoints.Geometry.GetGeometryBounds();
+ }
+ return null;
+ }
+
+ ///
+ /// Copy all characteristic point related data from another .
+ ///
+ /// Data source
+ public void Assign(SurfaceLine2 source)
+ {
+ SetValuesFromOtherSurfaceLine(source);
+ }
+
+ ///
+ /// Sets the values from another surface line.
+ ///
+ /// The source.
+ /// If set to true, the of
+ /// will be deep cloned, otherwise the reference is shared.
+ private void SetValuesFromOtherSurfaceLine(SurfaceLine2 source, bool cloneGeometry = false)
+ {
+ CharacteristicPoints.Clear(); // clears the whole characteristic points state.
+
+ Name = source.Name;
+ Geometry.Name = Name;
+ LandwardDirection = source.LandwardDirection;
+
+ CharacteristicPoints.GeometryMustContainPoint = source.CharacteristicPoints.GeometryMustContainPoint;
+ Geometry = cloneGeometry ? source.Geometry.Clone() : source.Geometry;
+
+ var geometryAnnotations = GetCharacteristicAnnotationsInSource(source, cloneGeometry);
+
+ // Reconstruct annotation state from dictionary:
+ if (CharacteristicPoints.GeometryMustContainPoint)
+ {
+ foreach (var annotation in geometryAnnotations)
+ {
+ for (int i = 0; i < annotation.Value.Length; i++)
+ {
+ var index = -1;
+ for (int j = 0; j < CharacteristicPoints.Count; j++)
+ {
+ if (ReferenceEquals(CharacteristicPoints[j].GeometryPoint, annotation.Key))
+ {
+ index = j;
+ break;
+ }
+ }
+
+ if (i == 0)
+ {
+ // Reassign annotation of already created CharacteristicPoint:
+ CharacteristicPoints.Annotate(index, annotation.Value[i]);
+ }
+ else
+ {
+ // Add new CharacteristicPoint instance for all subsequent annotations and ensuring to keep the defined order:
+ CharacteristicPoints.Insert(index + i, new CharacteristicPoint(CharacteristicPoints, annotation.Key)
+ {
+ CharacteristicPointType = annotation.Value[i]
+ });
+ }
+ }
+ }
+ }
+ else
+ {
+ foreach (var annotation in geometryAnnotations)
+ {
+ AddCharacteristicPoint((GeometryPoint)annotation.Key.Clone(), annotation.Value);
+ }
+ }
+ }
+
+ ///
+ /// Collapses all characteristic point annotations in the given surfaceline into
+ /// a dictionary keyed on instances in that surfaceline
+ /// and their annotations.
+ ///
+ /// The referenced surfaceline.
+ /// True if should be a clone from
+ /// .; false if it should
+ /// take the same instance instead.
+ /// Dictionary keyed on instances in the surfaceline
+ /// that have annotations.
+ private Dictionary GetCharacteristicAnnotationsInSource(SurfaceLine2 source, bool cloneGeometry)
+ {
+ return CharacteristicPoints.GeometryMustContainPoint
+ ? GetCharacteristicAnnotationsInSource_GeometryMustContainPoints(source, cloneGeometry)
+ : GetCharacteristicAnnotationsInSource_GeometryMustNotContainPoints(source);
+ }
+
+ ///
+ /// Handlers return value in case
+ /// is true.
+ ///
+ /// The referenced surfaceline.
+ /// True if should be a clone from
+ /// .; false if it should
+ /// take the same instance instead.
+ /// Dictionary keyed on instances in the surfaceline
+ /// that have annotations.
+ private Dictionary GetCharacteristicAnnotationsInSource_GeometryMustContainPoints(SurfaceLine2 source, bool cloneGeometry)
+ {
+ var geometryAnnotations = new Dictionary();
+ for (int i = 0; i < source.Geometry.Count; i++)
+ {
+ var annotationsForPoint = source.GetCharacteristicPoints(source.Geometry.Points[i]).Where(cpt => cpt != CharacteristicPointType.None).ToArray();
+ if (annotationsForPoint.Length > 0)
+ {
+ geometryAnnotations[Geometry.Points[i]] = annotationsForPoint;
+ }
+ }
+ return geometryAnnotations;
+ }
+
+ ///
+ /// Handles return value in case
+ /// is false.
+ ///
+ /// The referenced surfaceline.
+ /// Dictionary keyed on instances in the surfaceline
+ /// that have annotations.
+ private static Dictionary GetCharacteristicAnnotationsInSource_GeometryMustNotContainPoints(SurfaceLine2 source)
+ {
+ var geometryAnnotations = new Dictionary();
+ foreach (var characteristicPoint in source.CharacteristicPoints)
+ {
+ if (!geometryAnnotations.ContainsKey(characteristicPoint.GeometryPoint))
+ {
+ geometryAnnotations[characteristicPoint.GeometryPoint] =
+ source.GetCharacteristicPoints(characteristicPoint.GeometryPoint).ToArray();
+ }
+ }
+ return geometryAnnotations;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/IGeometryObject.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/IGeometryObject.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/IGeometryObject.cs (revision 334)
@@ -0,0 +1,37 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// interface IGeometryObject
+ ///
+ public interface IGeometryObject
+ {
+ ///
+ /// Gets or sets the name.
+ ///
+ ///
+ /// The name.
+ ///
+ string Name { set; get; }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityCalculator.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityCalculator.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/Stability/StabilityCalculator.cs (revision 334)
@@ -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/trunk/src/Deltares.DamEngine.Calculators/Dikes Assessment Regional/UpliftRWEvaluator.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Calculators/Dikes Assessment Regional/UpliftRWEvaluator.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Calculators/Dikes Assessment Regional/UpliftRWEvaluator.cs (revision 334)
@@ -0,0 +1,150 @@
+// 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 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.Calculators.Dikes_Assessment_Regional
+{
+ public class UpliftRWEvaluator : RWEvaluator
+ {
+ private DikeDrySensitivity dikeDrySensitivity = DikeDrySensitivity.None;
+ private LoadSituation loadSituation = LoadSituation.Wet;
+ private HydraulicShortcutType hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
+
+ public UpliftRWEvaluator()
+ {
+ }
+
+ public override Enum Evaluate(Location location, SoilGeometry soilGeometry, params Enum[] previousChoices)
+ {
+ base.Evaluate(location, soilGeometry, previousChoices);
+
+ Dictionary choices = new Dictionary();
+ foreach (Enum enumValue in previousChoices)
+ {
+ if (enumValue != null)
+ {
+ choices[enumValue.GetType()] = enumValue;
+ }
+ }
+ dikeDrySensitivity = (DikeDrySensitivity)choices[typeof(DikeDrySensitivity)];
+ loadSituation = (LoadSituation)choices[typeof(LoadSituation)];
+ hydraulicShortcutType = (HydraulicShortcutType) choices[typeof (HydraulicShortcutType)];
+ // determine uplift here
+
+ double? upliftFactor = GetLowestUpliftFactor();
+ UpliftType upliftType = UpliftType.NoUplift;
+ if (upliftFactor != null)
+ {
+ if (upliftFactor.Value < location.ModelFactors.UpliftCriterionStability)
+ {
+ return UpliftType.Uplift;
+ }
+ }
+ return upliftType;
+ }
+
+ ///
+ /// Create PL-lines
+ ///
+ ///
+ private PLLines CreatePLLines()
+ {
+ PLLinesCreator plLinesCreator = new PLLinesCreator();
+ double waterLevel = GetBoezemLevel();
+
+ plLinesCreator.WaterLevelRiverHigh = waterLevel;
+ 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.DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil();
+ plLinesCreator.IsUseOvenDryUnitWeight = (dikeDrySensitivity == DikeDrySensitivity.Dry);
+ plLinesCreator.IsHydraulicShortcut = (hydraulicShortcutType == HydraulicShortcutType.HydraulicShortcut);
+ plLinesCreator.XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin;
+
+// PLLines plLines = plLinesCreator.CreateAllPLLines(location);
+// return plLines; ##Bka
+ return null;
+ }
+
+ ///
+ /// Determine boezemlevel according to loadsituation
+ ///
+ ///
+ private double GetBoezemLevel()
+ {
+ double boezemLevel = 0.0;
+ switch (loadSituation)
+ {
+ case LoadSituation.Wet:
+ boezemLevel = location.BoezemLevelTp;
+ break;
+ case LoadSituation.Dry:
+ boezemLevel = location.BoezemLevelHbp;
+ break;
+ }
+ return boezemLevel;
+ }
+
+ ///
+ /// Determine where lowest uplift factor occurs and the value of that factor
+ ///
+ ///
+ private double? GetLowestUpliftFactor()
+ {
+
+ UpliftLocationDeterminator upliftLocationDeterminator = new UpliftLocationDeterminator()
+ {
+ SurfaceLine = location.LocalXZSurfaceLine2,
+ SoilProfile = soilGeometry.SoilProfile,
+ SoilGeometry2DName = null,
+ 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/trunk/src/Deltares.DamEngine.Data/Geometry/LineHelper.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/LineHelper.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/LineHelper.cs (revision 334)
@@ -0,0 +1,165 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Helper class for Line objects
+ ///
+ 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.
+ ///
+ /// Circle's middle point X value
+ /// Circle's middle point Z value
+ /// Circle's radius
+ /// Point collection which defines a line. Extrapolation is performed at the start and end points.
+ /// Intersections of this line extrapolated to the negative and positive X with the circle.
+ public static List ExtendedSurfaceIntersectionPointsWithCircle(double xMid, double zMid, double radius, IList pointss)
+ {
+ var points = pointss.Where(p => !double.IsNaN(p.X)).ToList();
+ if (points.Count >= 2)
+ {
+ var requiredMinSurfacePointX = xMid - radius;
+ var requiredMaxSurfacePointX = xMid + radius;
+ if (requiredMinSurfacePointX < points[0].X)
+ {
+ points.Insert(0, new Point2D{ X = requiredMinSurfacePointX, Z = points[0].Z});
+ }
+ if (requiredMaxSurfacePointX > points[points.Count - 1].X)
+ {
+ points.Insert(points.Count, new Point2D{ X = requiredMaxSurfacePointX, Z = points[points.Count - 1].Z});
+ }
+ }
+ return IntersectionPointsWithCircle(xMid, zMid, radius, points);
+ }
+
+ ///
+ /// Intersections the points with circle.
+ ///
+ /// The x mid.
+ /// The z mid.
+ /// The radius.
+ /// The points.
+ ///
+ public static List IntersectionPointsWithCircle(double xMid, double zMid, double radius, IList points)
+ {
+ var result = new List();
+ if (points.Count >= 2)
+ {
+ for (int pointIndex = 0; pointIndex < points.Count - 1; pointIndex++)
+ {
+ var start = points[pointIndex];
+ var end = points[pointIndex + 1];
+ var outOfReach = ((Math.Max(start.X, end.X) < xMid - radius) ||
+ (Math.Min(start.X, end.X) > xMid + radius) ||
+ (Math.Max(start.Z, end.Z) < zMid - radius) ||
+ (Math.Min(start.Z, end.Z) > zMid + radius));
+ if (!outOfReach)
+ {
+ var line = new Line
+ {
+ BeginPoint = start, EndPoint = end
+ };
+ result.AddRange(Intersect_Circle_line(xMid, zMid, radius, line));
+ }
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// Intersects the circle line.
+ ///
+ /// The xm.
+ /// The ym.
+ /// The r.
+ /// The line.
+ ///
+ private static List Intersect_Circle_line(double xm, double ym, double r, Line line)
+ {
+ 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/trunk/src/Deltares.DamEngine.Data/General/DamProjectCalculationSpecification.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/DamProjectCalculationSpecification.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/DamProjectCalculationSpecification.cs (revision 334)
@@ -0,0 +1,153 @@
+// 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.Collections.Generic;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.Standard.Language;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.General
+{
+ ///
+ /// Represents the calculation specifications at project level for DAM.
+ /// These are the main choices that specify the calculation
+ ///
+ public class DamProjectCalculationSpecification
+ {
+ private readonly List damCalculationSpecifications;
+
+ private static AnalysisType selectedAnalysisType = AnalysisType.AdaptGeometry;
+ private ProbabilisticType selectedProbabilisticType;
+ private DamFailureMechanismeCalculationSpecification currentSpecification;
+ private StabilityKernelType selectedStabilityKernelType;
+
+ public DamProjectCalculationSpecification()
+ {
+ damCalculationSpecifications = new List();
+ //waterLevelTimeSeriesFileName = @"d:\src\delftgeosystems\trunk\data\Dam\RRD\Groot Salland\DAM UI Testdata\inputshortstart_dam.xml";
+ }
+
+ [Validate]
+ public List DamCalculationSpecifications
+ {
+ get
+ {
+
+ if (currentSpecification != null && currentSpecification.FailureMechanismSystemType != FailureMechanismSystemType.Piping)
+ {
+ selectedProbabilisticType = ProbabilisticType.Deterministic;
+ }
+ return damCalculationSpecifications;
+ }
+ }
+
+ ///
+ /// Gets or sets the analysis type for serialization purpose only.
+ /// This "dummy" property is and must be only used for serialization/deserialization purposes as the real static property
+ /// SelectedAnalysisType is NOT serialized. This is way its name is deliberately strange.
+ ///
+ ///
+ /// The analysis type for serialization purpose only.
+ ///
+ public AnalysisType AnalysisTypeForSerializationPurposeOnly
+ {
+ get
+ {
+ return selectedAnalysisType;
+ }
+ set
+ {
+ selectedAnalysisType = value;
+ }
+
+ }
+
+ ///
+ /// Gets or sets the type of the selected analysis.
+ ///
+ ///
+ /// The type of the selected analysis.
+ ///
+ public static AnalysisType SelectedAnalysisType
+ {
+ get { return selectedAnalysisType; }
+ set
+ {
+ selectedAnalysisType = value;
+ }
+ }
+
+ public ProbabilisticType SelectedProbabilisticType
+ {
+ get { return selectedProbabilisticType; }
+ set
+ {
+ selectedProbabilisticType = value;
+ DamFailureMechanismeCalculationSpecification.ProbabilisticType = selectedProbabilisticType;
+ }
+ }
+
+ [XmlIgnore]
+ public DamFailureMechanismeCalculationSpecification CurrentSpecification
+ {
+ get
+ {
+ if (currentSpecification == null && damCalculationSpecifications.Count > 0)
+ {
+ currentSpecification = damCalculationSpecifications[0];
+ }
+
+ return currentSpecification;
+ }
+ set
+ {
+ currentSpecification = value;
+ }
+ }
+
+ public StabilityKernelType SelectedStabilityKernelType
+ {
+ get { return selectedStabilityKernelType; }
+ set
+ {
+ selectedStabilityKernelType = value;
+ if (currentSpecification != null)
+ {
+ currentSpecification.StabilityKernelType = selectedStabilityKernelType;
+ }
+ }
+ }
+
+ [Validate]
+ public ValidationResult[] Validate()
+ {
+ if (damCalculationSpecifications.Count > 1)
+ {
+ return new[]{ new ValidationResult(ValidationResultType.Error, LocalizationManager.GetTranslatedText(this, "MaxOneCalculationSpecification"),
+ this)};
+ }
+ else
+ {
+ return new ValidationResult[0];
+ }
+ }
+ }
+}
Index: dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/PipingResults.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/PipingResults.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/General/Results/PipingResults.cs (revision 334)
@@ -0,0 +1,42 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General.Results
+{
+ public struct PipingResults
+ {
+ public string CalculationName { get; set; }
+ public string CalculationSubDir { get; set; }
+ public double? BlighPipingFactor { get; set; }
+ public double? BlighHCritical { get; set; }
+ public double? Sellmeijer2ForcesPipingFactor { get; set; }
+ public double? Sellmeijer2ForcesHCritical { get; set; }
+ public double? Sellmeijer4ForcesPipingFactor { get; set; }
+ public double? Sellmeijer4ForcesHCritical { get; set; }
+ public double? SellmeijerPipingFactor { get; set; }
+ public double? SellmeijerHCritical { get; set; }
+ public double? Wti2017PipingFactor { get; set; }
+ public double? Wti2017HCritical { get; set; }
+ public double? PipingExitPointX { get; set; }
+ public double? UpliftFactor { get; set; }
+ public double? HeaveFactor { get; set; }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Probabilistic/Enumerations.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Probabilistic/Enumerations.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Probabilistic/Enumerations.cs (revision 334)
@@ -0,0 +1,86 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.Probabilistic
+{
+ public enum ProbabilisticMethod
+ {
+ FORM,
+ MonteCarlo, // Crude MonteCarlo
+ DirectionalSampling,
+ NumericalIntegration,
+ ImportanceSampling, // MonteCarlo Importance sampling
+ FOSM
+ }
+
+ public enum DistributionType
+ {
+ Deterministic = 0,
+ Uniform = 1,
+ Triangular = 11,
+ Normal = 2,
+ LogNormal = 3, // will convert to log normal II in HydraRing
+
+ //[Label("Log normal II")]
+ //LogNormalII = 31,
+
+ Exponential = 4,
+ Gamma = 5,
+ Beta = 6,
+ Frechet = 7,
+ Weibull = 8,
+ Gumbel = 9,
+ Rayleigh =10,
+ Pareto = 16,
+ TruncatedNormal = 12,
+ Table = 13,
+ StudentT = 14
+ }
+
+ public enum StartMethodType
+ {
+ StartZero = 1,
+ StartOne = 2,
+ StartGivenVector = 3,
+ StartRaySearch = 4,
+ StartSphereSearch = 5
+ }
+
+ public enum ProbabilisticOutputType
+ {
+ Model,
+ DesignPoint,
+ BandWidth
+ }
+
+ public enum QualitativeValue
+ {
+ Low,
+ Medium,
+ High
+ }
+
+ public enum SourceLocationType
+ {
+ Internal,
+ External
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryObject.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryObject.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryObject.cs (revision 334)
@@ -0,0 +1,86 @@
+// 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.Standard;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Base class for all Geometry objects
+ ///
+ [Serializable]
+ public abstract class GeometryObject : IGeometryObject, IName
+ {
+ private string name = "";
+
+ ///
+ /// Sets the name.
+ ///
+ /// The new name.
+ public virtual void SetName(string newName)
+ {
+ name = newName; // TODO: Name is virtual. Is this really expected behavior?
+ }
+
+ ///
+ /// Gets the geometry bounds.
+ ///
+ ///
+ public virtual GeometryBounds GetGeometryBounds()
+ {
+ return null;
+ }
+
+ #region IGeometryObject Members
+
+ ///
+ /// Gets or sets the name.
+ ///
+ ///
+ /// The name.
+ ///
+ public virtual string Name
+ {
+ get
+ {
+ return name;
+ }
+ set
+ {
+ name = value;
+ }
+ }
+
+ #endregion
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/trunk/src/Deltares.DamEngine.Data/Design/Scenario.cs
===================================================================
diff -u
--- dam engine/trunk/src/Deltares.DamEngine.Data/Design/Scenario.cs (revision 0)
+++ dam engine/trunk/src/Deltares.DamEngine.Data/Design/Scenario.cs (revision 334)
@@ -0,0 +1,1400 @@
+// 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.Collections.Specialized;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq.Expressions;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.General;
+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.Validation;
+
+namespace Deltares.DamEngine.Data.Design
+{
+
+ ///
+ /// Does uplift occur or not
+ ///
+ public struct UpliftSituation
+ {
+ public bool IsUplift;
+ public double Pl3MinUplift;
+ public double Pl3HeadAdjusted;
+ public double Pl3LocationXMinUplift;
+ public double Pl4MinUplift;
+ public double Pl4HeadAdjusted;
+ public double Pl4LocationXMinUplift;
+ }
+
+ [Serializable]
+ public class ScenarioException : Exception
+ {
+ public ScenarioException(string message) : base(message)
+ {
+ }
+ }
+
+ ///
+ /// Calculation scenario class
+ ///
+ public class Scenario
+ {
+ #region Performance optimization: Extract expression so it only has to be generated once.
+
+ private static readonly Expression> ExpressionLocationScenarioId = x => x.LocationScenarioID;
+ private static readonly Expression> ExpressionRiverLevel = x => x.RiverLevel;
+ private static readonly Expression> ExpressionRiverLevelLow = x => x.RiverLevelLow;
+ private static readonly Expression