Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculatorException.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculatorException.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculatorException.cs (revision 274)
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2010 Deltares. All rights reserved.
+//
+// B.S.T. The
+// tom.the@deltares.nl
+// 04-11-2010
+// n.a.
+//-----------------------------------------------------------------------
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Deltares.DamEngine.Calculators
+{
+ [Serializable]
+ public class DamFailureMechanismeCalculatorException : Exception
+ {
+ public DamFailureMechanismeCalculatorException()
+ {
+ }
+
+ public DamFailureMechanismeCalculatorException(string message)
+ : base(message)
+ {
+ }
+
+ public DamFailureMechanismeCalculatorException(string message, Exception inner)
+ : base(message, inner)
+ {
+ }
+
+ protected DamFailureMechanismeCalculatorException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+ public Scenario Scenario { get; set; }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/DilatancyType.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/DilatancyType.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/DilatancyType.cs (revision 274)
@@ -0,0 +1,44 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs (revision 274)
@@ -0,0 +1,2001 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2009 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 16-12-2009
+// Perform single calculation which is specified in DamFailureMechanismeCalculationSpecification
+//-----------------------------------------------------------------------
+
+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.Dam.Data;
+using Deltares.DamEngine.Data.Design;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Geotechnics;
+
+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)
+ {
+ adaptedSurfaceLine.Dispose();
+ 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(DamProject.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/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/PreConsolidationStress.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/PreConsolidationStress.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/PreConsolidationStress.cs (revision 274)
@@ -0,0 +1,105 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Standard.Language;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Pre-consolidation stress used within preproces stability
+ ///
+ public class PreConsolidationStress : GeometryPoint
+ {
+ ///
+ /// Initializes a new instance of the class
+ /// as a XZ point.
+ ///
+ public PreConsolidationStress()
+ {
+ StressValue = double.NaN;
+ }
+
+ ///
+ /// Gets or sets the stress value.
+ ///
+ [XmlIgnore]
+ public double StressValue { get; set; }
+
+ ///
+ /// Gets or sets the name.
+ ///
+ ///
+ /// The name.
+ ///
+ public override string Name { get; set; }
+
+
+ ///
+ /// Gets or sets the X coordinate of publisherEventArgs GeometryPoint
+ ///
+ [Translation("XCoordYieldStress")]
+ public override double X
+ {
+ get
+ {
+ return base.X;
+ }
+ set
+ {
+ base.X = value;
+ }
+ }
+
+
+ ///
+ /// Gets or sets the Z coordinate of publisherEventArgs GeometryPoint
+ ///
+ [Translation("ZCoordYieldStress")]
+ public override double Z
+ {
+ get
+ {
+ return base.Z;
+ }
+ set
+ {
+ base.Z = value;
+ }
+ }
+
+ ///
+ /// Clones this instance.
+ ///
+ public override object Clone()
+ {
+ var clone = new PreConsolidationStress
+ {
+ Name = Name,
+ StressValue = StressValue,
+ X = X,
+ Z = Z
+ };
+ return clone;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/IGeometryObject.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/IGeometryObject.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/IGeometryObject.cs (revision 274)
@@ -0,0 +1,37 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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/branches/Initial Source/Deltares.DamEngine.Data/Standard/ISortableList.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ISortableList.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ISortableList.cs (revision 274)
@@ -0,0 +1,39 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard
+{
+ ///
+ /// Interface ISortableList
+ ///
+ public interface ISortableList
+ {
+ ///
+ /// Sorts this instance.
+ ///
+ void Sort();
+
+ ///
+ /// Reverses this instance.
+ ///
+ void Reverse();
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryObject.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryObject.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryObject.cs (revision 274)
@@ -0,0 +1,86 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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/branches/Initial Source/Deltares.DamEngine.Data/Standard/ObjectExtensions.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ObjectExtensions.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ObjectExtensions.cs (revision 274)
@@ -0,0 +1,139 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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 System.Reflection;
+
+namespace Deltares.DamEngine.Data.Standard
+{
+ ///
+ /// Static class ObjectExtensions
+ ///
+ public static class ObjectExtensions
+ {
+ private const double threshold = 0.0000001;
+
+ ///
+ /// Tests two double values for equality with a default precision of
+ ///
+ /// The first double value
+ /// The other double value to compare with
+ /// True when almost equal
+ public static bool AlmostEquals(this double double1, double double2)
+ {
+ return AlmostEquals(double1, double2, threshold);
+ }
+
+ ///
+ /// Tests two double values for equality with a given precision
+ ///
+ /// The first double value
+ /// The other double value to compare with
+ /// The precision value
+ /// True when almost equal
+ public static bool AlmostEquals(this double double1, double double2, double precision)
+ {
+ if (double.IsNaN(double1) && double.IsNaN(double2))
+ {
+ return true;
+ }
+
+ if (double.IsNaN(double1) || double.IsNaN(double2))
+ {
+ return false;
+ }
+
+ return (Math.Abs(double1 - double2) <= precision);
+ }
+
+ ///
+ /// Clone properties from an original object to a destination object.
+ ///
+ ///
+ /// Copy matching properties from object to object
+ /// http://goneale.wordpress.com/2009/02/16/cloning-object-properties-via-reflection/#
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void CloneProperties(this T1 origin, T2 destination, params string[] excludedProperties)
+ {
+ // Instantiate if necessary
+ if (destination == null)
+ {
+ throw new ArgumentNullException("destination", "Destination object must first be instantiated.");
+ }
+ // Loop through each property in the destination
+ foreach (var destinationProperty in destination.GetType().GetProperties())
+ {
+ bool excluded = false;
+ foreach (var excludedProperty in excludedProperties)
+ {
+ if (excludedProperty.ToLower().Equals(destinationProperty.Name.ToLower()))
+ {
+ excluded = true;
+ }
+ }
+
+ if (excluded || IsIList(destinationProperty) || IsIDictionary(destinationProperty)
+ || IsGenericIList(destinationProperty) || IsGenericIDictionary(destinationProperty))
+ {
+ continue;
+ }
+ // find and set val if we can find a matching property name and matching type in the origin with the origin's value
+ if (!origin.Equals(default(T1)) && destinationProperty.CanWrite)
+ {
+ PropertyInfo propertyInfo = destinationProperty;
+ origin.GetType().GetProperties().Where(
+ x => x.CanRead && (x.Name == propertyInfo.Name && x.PropertyType == propertyInfo.PropertyType))
+ .ToList()
+ .ForEach(x => propertyInfo.SetValue(destination, x.GetValue(origin, null), null));
+ }
+ }
+ }
+
+ private static bool IsGenericIDictionary(PropertyInfo destinationProperty)
+ {
+ return destinationProperty.PropertyType.IsGenericType && destinationProperty.PropertyType.GetGenericTypeDefinition() == typeof(IDictionary<,>);
+ }
+
+ private static bool IsIDictionary(PropertyInfo destinationProperty)
+ {
+ return typeof(IDictionary).IsAssignableFrom(destinationProperty.PropertyType);
+ }
+
+ private static bool IsGenericIList(PropertyInfo destinationProperty)
+ {
+ return destinationProperty.PropertyType.IsGenericType && destinationProperty.PropertyType.GetGenericTypeDefinition() == typeof(IList<>);
+ }
+
+ private static bool IsIList(PropertyInfo destinationProperty)
+ {
+ return typeof(IList).IsAssignableFrom(destinationProperty.PropertyType);
+ }
+
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamRunner.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamRunner.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamRunner.cs (revision 274)
@@ -0,0 +1,241 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Calculators.Dikes_Assessment;
+using Deltares.DamEngine.Data.Design;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.RWScenarios;
+using Deltares.DamEngine.Data.Standard.Calculation;
+
+namespace Deltares.DamEngine.Calculators
+{
+ public class DamRunner
+ {
+ private readonly DamProjectData damProjectData;
+ private readonly string directory = "";
+ private int maxCalculationCores = 255;
+ private DateTime startTimeCalculation;
+
+ public DamRunner(DamProjectData damProjectData, string projectFileName)
+ {
+ damProjectData = damProjectData;
+ directory = Path.GetDirectoryName(projectFileName);
+ }
+
+ private delegate void ProcessResultDelegate(DamProjectData damProject, CalculationResult result, string output);
+
+ private void ProcessResultLocal(DamProjectData damProject, CalculationResult result, string output)
+ {
+ damProjectData.UpdateCalculations();
+ damProjectData.UpdateSchematizationFactors();
+
+ TimeSpan elapsedTime = DateTime.Now - startTimeCalculation;
+ string timeMessage = String.Format(LocalizationManager.GetTranslatedText(this, "CalculationTime"), elapsedTime.ToString(@"dd\.hh\:mm\:ss"));
+ string paragraphSepatator = Environment.NewLine + Environment.NewLine;
+ if (output.StartsWith("Thread was being aborted"))
+ {
+ LocalizedMessageBox.Show(this, "CalculationAborted");
+ }
+ else if (result == CalculationResult.Succeeded)
+ {
+ string openingMessage = LocalizationManager.GetTranslatedText(this, "CalculationFinished");
+ LocalizedMessageBox.ShowTranslatedText(openingMessage + paragraphSepatator + timeMessage + paragraphSepatator + output);
+ }
+ else if ((result == CalculationResult.RunFailed) || (result == CalculationResult.UnexpectedError))
+ {
+ string openingMessage = LocalizationManager.GetTranslatedText(this, "CalculationFailed");
+ LocalizedMessageBox.ShowTranslatedText(openingMessage + paragraphSepatator + output);
+ }
+ }
+
+ private void ProcessResult(DamProjectData damProject, CalculationResult result, string output)
+ {
+ if (BindSupport.InvokeControl.InvokeRequired)
+ {
+ var d = new ProcessResultDelegate(ProcessResultLocal);
+ BindSupport.InvokeControl.Invoke(d, new object[] { damProject, result, output });
+ }
+ else
+ {
+ ProcessResultLocal(damProject, result, output);
+ }
+ }
+
+ public void PerformCalculation(ProgressDelegate progressDelegate)
+ {
+ startTimeCalculation = DateTime.Now;
+ try
+ {
+ switch (damProjectData.DamProjectType)
+ {
+ case DamProjectType.Calamity:
+ {
+ var damCalculation = new DamCalculation();
+
+ damCalculation.RegisterProgress(progressDelegate);
+ damCalculation.RegisterSendMessage(HandleCalculationSendMessage);
+ damCalculation.ProjectWorkingDirectory = ""; // Force default location for working directory
+ damCalculation.ProjectDataDirectory = directory + Path.DirectorySeparatorChar;
+ damCalculation.MStabExePath = StabilityCalculator.MStabExePath;
+ damCalculation.MaxCalculationCores = MaxCalculationCores;
+ damCalculation.CalculateDamProject(damProjectData);
+ var output = FillOutputForMessage(damProjectData.LocationJobs);
+ ProcessResult(damProjectData, CalculationResult.Succeeded, output);
+ break;
+ }
+ case DamProjectType.Assessment:
+ {
+ var rwScenariosCalculation = new RWScenariosCalculation
+ {
+ SchematizationFactorData = damProjectData.SchematizationFactorData,
+ MaxCalculationCores = MaxCalculationCores
+ };
+
+ rwScenariosCalculation.RegisterProgress(progressDelegate);
+ rwScenariosCalculation.RegisterSendMessage(HandleCalculationSendMessage);
+ rwScenariosCalculation.MStabExePath = StabilityCalculator.MStabExePath;
+ rwScenariosCalculation.PipingModelType = damProjectData.DamProjectCalculationSpecification.CurrentSpecification.PipingModelType;
+ rwScenariosCalculation.MStabParameters =
+ damProjectData.DamProjectCalculationSpecification.CurrentSpecification
+ .FailureMechanismeParamatersMStab.MStabParameters;
+ EvaluationJob evaluationJob = damProjectData.GetEvaluationJob();
+
+ RemoveLogMessages(evaluationJob);
+ CalculationResult calculationResult;
+ try
+ {
+ rwScenariosCalculation.Load(evaluationJob.XML);
+ calculationResult = rwScenariosCalculation.Run();
+ DataEventPublisher.DataListModified(LogManager.Messages);
+ }
+ catch (Exception)
+ {
+ calculationResult = CalculationResult.UnexpectedError;
+ }
+
+ string results = "";
+ rwScenariosCalculation.GetResults(ref results);
+
+ evaluationJob.XML = results;
+ evaluationJob.AttachResults(damProjectData.LocationJobs);
+ var output = FillOutputForMessage(damProjectData.LocationJobs);
+ ProcessResult(damProjectData, calculationResult, output);
+ break;
+ }
+ case DamProjectType.Design:
+ {
+ if (damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications.Count > 0)
+ {
+ List scenarios = CreateScenarioListForCalculation();
+ var damProjectCalculator = new DamProjectCalculator(damProjectData)
+ {
+ MaxCalculationCores = MaxCalculationCores,
+ MStabProgramPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "DGeoStability.exe"),
+ SlopeWProgramPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Slope2.exe"),
+ ProjectDataDirectory = directory + Path.DirectorySeparatorChar,
+ Progress = progressDelegate,
+ CalculationBaseDirectory = DamProject.ProjectWorkingPath + @"\CalculationFiles\"
+ };
+
+ damProjectCalculator.Calculate(damProjectData, scenarios);
+ var output = FillOutputForMessage(damProjectData.LocationJobs);
+ ProcessResult(damProjectData, CalculationResult.Succeeded, output);
+ }
+ }
+ break;
+ }
+ }
+ catch (Exception exception)
+ {
+ var sb = new StringBuilder(exception.Message);
+ for (Exception innerException = exception.InnerException; innerException != null; innerException = innerException.InnerException)
+ {
+ sb.Append('\n');
+ sb.Append(innerException.Message);
+ }
+
+ ProcessResult(damProjectData, CalculationResult.RunFailed, sb.ToString());
+ }
+ }
+
+
+ private string FillOutputForMessage(IEnumerable locationJobs)
+ {
+ var res = "";
+ foreach (var locationJob in locationJobs)
+ {
+ if (locationJob.Result == JobResult.Failed)
+ {
+ var failedLocationCalculation = LocalizationManager.GetTranslatedText(GetType(), "failedLocationCalculationId");
+ res = res + String.Format(failedLocationCalculation, locationJob.Location.Name) + Environment.NewLine;
+ }
+ else
+ {
+ if (locationJob.Result != JobResult.NoRun && !locationJob.HasLocationResults
+ && !locationJob.HasRWScenarioResults && !locationJob.HasScenarioResults)
+ {
+ var noResultsForLocation = LocalizationManager.GetTranslatedText(GetType(), "noResultsForLocationId");
+ res = res + String.Format(noResultsForLocation, locationJob.Location.Name) + Environment.NewLine;
+ }
+ }
+ }
+ return res;
+ }
+
+
+ ///
+ /// Create a list of scenarios to be calculated
+ ///
+ /// List of the generated scenarios
+ private List CreateScenarioListForCalculation()
+ {
+ var scenarios = new List();
+
+ // The locations of the scenarios can get out of sync after a calculation, so make sure they are in sync
+ damProjectData.WaterBoard.UpdateLocationsForScenarios();
+
+ List selectedLocations = damProjectData.SelectedLocationJobs.Select(x => x.Location).ToList();
+ foreach (var location in selectedLocations)
+ {
+ scenarios.AddRange(location.Scenarios);
+ }
+
+ return scenarios;
+ }
+
+ private void RemoveLogMessages(EvaluationJob evaluationJob)
+ {
+ foreach (LogMessage logMessage in LogManager.Messages.ToArray())
+ {
+ foreach (var location in evaluationJob.Locations)
+ {
+ if (logMessage.SubjectName.Equals(location.ToString()))
+ {
+ LogManager.Messages.Remove(logMessage);
+ }
+ }
+ }
+
+ DataEventPublisher.DataListModified(LogManager.Messages);
+ }
+
+ private void HandleCalculationSendMessage(LogMessage logMessage)
+ {
+ lock (LogManager.Messages)
+ {
+ LogManager.Messages.Add(logMessage);
+ DataEventPublisher.DataListModified(LogManager.Messages);
+ }
+ }
+
+ public int MaxCalculationCores
+ {
+ get { return maxCalculationCores; }
+ set { maxCalculationCores = value; }
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/HydraulicShortcutRWEvaluator.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/HydraulicShortcutRWEvaluator.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/HydraulicShortcutRWEvaluator.cs (revision 274)
@@ -0,0 +1,274 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2011 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 18-05-2010
+// Hydraulic shortcut evaluator
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Data.General;
+
+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();
+ 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/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWResult.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWResult.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWResult.cs (revision 274)
@@ -0,0 +1,66 @@
+using System.ComponentModel;
+using Deltares.Dam.Data;
+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/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryCurve.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryCurve.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryCurve.cs (revision 274)
@@ -0,0 +1,207 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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
+{
+ ///
+ /// Represents the possible directions of the curve
+ ///
+ public enum CurveDirection
+ {
+ ///
+ /// Unknown as direction
+ ///
+ Unknown = -1,
+ ///
+ /// Forward as direction
+ ///
+ Forward = 0,
+ ///
+ /// Reverse as direction
+ ///
+ Reverse = 1
+ }
+
+ ///
+ /// Contains the collection of all the curves data.
+ ///
+ public class GeometryCurve : GeometryObject
+ {
+ private Point2D endPoint;
+ private Point2D headPoint;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GeometryCurve() {}
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The head point.
+ /// The end point.
+ public GeometryCurve(Point2D headPoint, Point2D endPoint)
+ {
+ this.headPoint = headPoint;
+ this.endPoint = endPoint;
+ }
+
+ ///
+ /// Gets or sets the head point of the curve.
+ ///
+ public virtual Point2D HeadPoint
+ {
+ get
+ {
+ return headPoint;
+ }
+ set
+ {
+ headPoint = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the end point of the curve.
+ ///
+ public virtual Point2D EndPoint
+ {
+ get
+ {
+ return endPoint;
+ }
+ set
+ {
+ endPoint = value;
+ }
+ }
+
+ ///
+ /// The unique name of the object.
+ ///
+ public override string Name
+ {
+ get
+ {
+ if (!string.IsNullOrEmpty(base.Name))
+ {
+ return base.Name;
+ }
+
+ string text = "";
+ if (HeadPoint != null)
+ {
+ text += HeadPoint.ToString().Trim();
+ }
+ text += "-";
+ if (EndPoint != null)
+ {
+ text += EndPoint.ToString().Trim();
+ }
+ return text;
+ }
+ set
+ {
+ base.Name = value;
+ }
+ }
+
+ ///
+ /// Swaps and .
+ ///
+ public void Reverse()
+ {
+ var point = HeadPoint;
+ HeadPoint = EndPoint;
+ EndPoint = point;
+ }
+
+ ///
+ /// Returns the head point in given direction
+ ///
+ /// Direction is either Forward or Reverse or Unknown
+ /// Returns the head point in the given direction
+ public Point2D GetHeadPoint(CurveDirection aDirection)
+ {
+ if (aDirection == CurveDirection.Forward)
+ {
+ return headPoint;
+ }
+
+ return endPoint;
+ }
+
+ ///
+ /// Gets the end point in the given direction
+ ///
+ /// Direction is either Forward or Reverse or Unknown
+ /// Returns the end point in the given direction
+ public Point2D GetEndPoint(CurveDirection aDirection)
+ {
+ if (aDirection == CurveDirection.Forward)
+ {
+ return endPoint;
+ }
+
+ return headPoint;
+ }
+
+ ///
+ /// Gets the geometry bounds.
+ ///
+ ///
+ public override GeometryBounds GetGeometryBounds()
+ {
+ if (HeadPoint != null && EndPoint != null)
+ {
+ var head = new GeometryBounds(HeadPoint.X, HeadPoint.X, HeadPoint.Z, HeadPoint.Z);
+ var end = new GeometryBounds(EndPoint.X, EndPoint.X, EndPoint.Z, EndPoint.Z);
+ return head + end;
+ }
+
+ return null;
+ }
+
+ ///
+ /// Determines whether the curve contains the specified point within the given tolerance.
+ ///
+ /// The point.
+ /// The tolerance.
+ ///
+ public bool ContainsPoint(Point2D point, double tolerance)
+ {
+ return HeadPoint != null && EndPoint != null &&
+ Routines2D.DoesPointExistInLine(HeadPoint.X, HeadPoint.Z, EndPoint.X, EndPoint.Z, point.X, point.Z, tolerance);
+ }
+
+ ///
+ /// Returns a string that represents the current object.
+ ///
+ ///
+ /// A string that represents the current object.
+ ///
+ /// 2
+ public override string ToString()
+ {
+ return string.Empty;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/AquitardEvaluator.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/AquitardEvaluator.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/AquitardEvaluator.cs (revision 274)
@@ -0,0 +1,143 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2011 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 09-06-2011
+// Evaluate thickness of aquitard layer
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+
+namespace Deltares.DamEngine.Data.RWScenarios
+{
+ public class AquitardEvaluatorException : Exception
+ {
+ public AquitardEvaluatorException(string message)
+ : base(message)
+ {
+ }
+ }
+
+ public class AquitardEvaluator
+ {
+ private SoilProfile1D soilProfile;
+ const double CMinimimalUnitWeightAquitard = 12.0; // kN/m2
+ public AquitardEvaluator(SoilProfile1D soilProfile)
+ {
+ this.soilProfile = soilProfile;
+ }
+
+ ///
+ /// Sum all aquitards between boezembottom and aquifer with a minimum weight of CMinimimalUnitWeightAquitard
+ ///
+ ///
+ ///
+ public double DetermineAquitardThicknessWithMinimalWeight(double surfaceLevel, Soil embankmentMaterial)
+ {
+ return DetermineAquitardThickness(surfaceLevel, true, embankmentMaterial);
+ }
+
+ ///
+ /// Sum all aquitards between boezembottom and aquifer without check on minimum weight
+ ///
+ ///
+ ///
+ public double DetermineAquitardThicknessWithoutMinimalWeight(double surfaceLevel, Soil embankmentMaterial)
+ {
+ return DetermineAquitardThickness(surfaceLevel, false, embankmentMaterial);
+ }
+
+ ///
+ /// Sum all aquitards between boezembottom and aquifer
+ ///
+ ///
+ ///
+ ///
+ private double DetermineAquitardThickness(double surfaceLevel, bool checkOnMinimalWeight, Soil embankmentMaterial)
+ {
+ ThrowExceptionWhenSurfaceLevelOutsideProfile(surfaceLevel, embankmentMaterial);
+
+ double aquitardBottomLevel = this.soilProfile.GetTopLevelOfHighestAquifer();
+ double thickness = 0.0;
+
+ List layers = new List(this.soilProfile.Layers);
+ if (surfaceLevel > soilProfile.TopLevel)
+ {
+ SoilLayer1D embankmentLayer = new SoilLayer1D(embankmentMaterial, surfaceLevel);
+ layers.Insert(0, embankmentLayer);
+ }
+
+ foreach (SoilLayer1D layer in layers)
+ {
+ bool includeLayer = true;
+
+ // Only include layer if soil has minimal weight
+ if (checkOnMinimalWeight)
+ {
+ includeLayer = layer.Soil.BelowPhreaticLevel >= CMinimimalUnitWeightAquitard;
+ }
+
+ // Only include layer if soil is waterremmend (clay or peat)
+ includeLayer = includeLayer && (layer.Soil.SoilType == SoilType.Clay || layer.Soil.SoilType == SoilType.Peat);
+ if (includeLayer)
+ {
+ double levelTop = Math.Min(surfaceLevel, layer.TopLevel);
+ double levelBottom = soilProfile.TopLevel;
+ if (soilProfile.Layers.Contains(layer))
+ {
+ levelBottom = Math.Max(aquitardBottomLevel, layer.TopLevel - soilProfile.GetLayerHeight(layer));
+ }
+
+ if (levelTop > levelBottom)
+ {
+ thickness += (levelTop - levelBottom);
+ }
+ }
+ }
+
+ return thickness;
+ }
+
+ public double DetermineAquitardClayThickness(double surfaceLevel)
+ {
+ ThrowExceptionWhenSurfaceLevelOutsideProfile(surfaceLevel, null);
+ //ThrowExceptionWhenMoreThan2Aquifers();
+ double aquitardBottomLevel = this.soilProfile.GetTopLevelOfHighestAquifer();
+ double thickness = 0.0;
+ foreach (SoilLayer1D layer in soilProfile.Layers)
+ {
+ if (layer.Soil.SoilType == SoilType.Clay)
+ {
+ double levelTop = Math.Min(surfaceLevel, layer.TopLevel);
+ double levelBottom = Math.Max(aquitardBottomLevel, layer.TopLevel - soilProfile.GetLayerHeight(layer));
+ if (levelTop > levelBottom)
+ {
+ thickness += (levelTop - levelBottom);
+ }
+ }
+ }
+ return thickness;
+ }
+
+ private void ThrowExceptionWhenSurfaceLevelOutsideProfile(double surfaceLevel, Soil embankmentMaterial)
+ {
+ if (surfaceLevel < soilProfile.BottomLevel || (surfaceLevel > soilProfile.TopLevel && embankmentMaterial == null))
+ {
+ throw new AquitardEvaluatorException(String.Format(
+ "Specified z-level {0} in AquitardEvaluator outside soilprofile '{1}' (should be between {2} and {3}",
+ surfaceLevel, soilProfile.Name, soilProfile.BottomLevel, soilProfile.TopLevel));
+ }
+ }
+
+ private void ThrowExceptionWhenMoreThan2Aquifers()
+ {
+ if (soilProfile.GetAquiferLayers().Count > 2)
+ {
+ throw new AquitardEvaluatorException("Soilprofile has more than 2 aquifers");
+ }
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamProjectData.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamProjectData.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamProjectData.cs (revision 274)
@@ -0,0 +1,698 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2011 Deltares. All rights reserved.
+//
+// J. Bokma
+// j.bokma@deltares.nl
+// 02-02-2011
+// n.a.
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Xml.Serialization;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Data.Design;
+using Deltares.DamEngine.Data.RWScenarios;
+using Deltares.DamEngine.Data.Standard.Calculation;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class DamProjectData : Project, IDisposable
+ {
+ public readonly double MissValStabilitySafetyFactor = -1.0;
+ private WaterBoard waterBoard;
+ private DamProjectCalculationSpecification damProjectCalculationSpecification;
+ private WaterBoardJob waterBoardJob = null;
+ private DamProjectType damProjectType = DamProjectType.Calamity;
+ private ProgramType programType = ProgramType.MStab;
+ private string damDataSourceFileName = "";
+ private List jobs = new List();
+ private SchematizationFactorData schematizationFactorData = new SchematizationFactorData();
+ private List calculations = null; // will be created and initialized in property
+ private List designCalculations = null;
+ private List schematizationFactors = null;
+ private List dataSources = new List();
+ private string dataSourceEsriProjection = null;
+ private SensorData sensorData;
+
+ ///
+ /// Constructor
+ ///
+ public DamProjectData()
+ {
+ this.waterBoard = new WaterBoard();
+ this.waterBoardJob = null;
+ this.damProjectCalculationSpecification = new DamProjectCalculationSpecification();
+ }
+
+ ///
+ /// Toplevel object to hold waterboard data
+ ///
+ public virtual WaterBoard WaterBoard
+ {
+ get { return this.waterBoard; }
+ set
+ {
+ this.waterBoard = value;
+ if (this.waterBoardJob != null && this.waterBoardJob.Subject != value)
+ {
+ this.waterBoardJob = null;
+ }
+ }
+ }
+ ///
+ /// calculation specification for the project
+ ///
+ /// Composite relationship
+ [Validate]
+ public DamProjectCalculationSpecification DamProjectCalculationSpecification
+ {
+ get { return damProjectCalculationSpecification; }
+ set { damProjectCalculationSpecification = value; }
+
+ }
+
+ [Child]
+ public virtual DamJob WaterBoardJob
+ {
+ get
+ {
+ if (waterBoardJob == null)
+ {
+ waterBoardJob = new WaterBoardJob(this.waterBoard);
+ waterBoardJob.Subject = this.waterBoard;
+
+ foreach (Dike dike in waterBoard.Dikes)
+ {
+ CompositeJob dikeJob = new DikeJob(dike);
+ waterBoardJob.Jobs.Add(dikeJob);
+
+ foreach (Location location in dike.Locations)
+ {
+ LocationJob locationJob = new LocationJob(location);
+ dikeJob.Jobs.Add(locationJob);
+ }
+ }
+ }
+
+ return waterBoardJob;
+ }
+ set { waterBoardJob = value as WaterBoardJob; }
+ }
+
+ [ReadOnly(true)]
+ [Label("Calculation type")]
+ [Description("Indicates the purpose of the calculations")]
+ public virtual DamProjectType DamProjectType
+ {
+ get { return damProjectType; }
+ set
+ {
+ DataEventPublisher.BeforeChange(this, "DamProjectType");
+
+ bool modified = damProjectType != value;
+
+ damProjectType = value;
+ Location.DamProjectType = value;
+ DamFailureMechanismeCalculationSpecification.DamProjectType = value;
+
+ if (modified)
+ {
+ LocationJob.DamProjectType = damProjectType;
+ DataEventPublisher.DataListModified(this.LocationJobs);
+ }
+
+ DataEventPublisher.AfterChange(this, "DamProjectType");
+ }
+ }
+
+ [Label("DAM datasource file")]
+ [Description("Indicates which \".defx\" import definition file to use")]
+ public virtual string DamDataSourceFileName
+ {
+ get { return damDataSourceFileName; }
+ set
+ {
+ DataEventPublisher.BeforeChange(this, "DamDataSourceFileName");
+ damDataSourceFileName = value;
+ DataEventPublisher.AfterChange(this, "DamDataSourceFileName");
+ }
+ }
+
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public List Calculations
+ {
+ get
+ {
+ if (calculations == null)
+ {
+ calculations = new List();
+ this.UpdateCalculations();
+ }
+
+ return calculations;
+ }
+ }
+
+ ///
+ /// Clear all results
+ ///
+ public void ClearResults()
+ {
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ locationJob.LocationResult = new LocationResult();
+ foreach (Scenario scenario in locationJob.Location.Scenarios)
+ {
+ scenario.CalculationResults.Clear();
+ }
+ }
+ }
+
+ public void UpdateCalculations()
+ {
+ if (calculations != null)
+ {
+ calculations.Clear();
+
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ if (locationJob.HasRWScenarioResults)
+ {
+ foreach (RWScenarioResult locationResult in locationJob.RWScenarioResults)
+ {
+ calculations.AddRange(locationResult.RWScenarioProfileResults);
+ }
+ }
+ }
+
+ DataEventPublisher.DataListModified(this.calculations);
+ }
+ }
+
+ private List CreateScenarioListForDeletion()
+ {
+ List scenarios = new List(); ;
+
+ List locations = this.LocationJobs.Select(x => x.Location).ToList();
+ foreach (Location location in locations)
+ {
+ if (location.Scenarios != null)
+ {
+ scenarios.AddRange(location.Scenarios);
+ }
+ }
+
+ return scenarios;
+ }
+
+ private List CreateScenarioListForCalculation()
+ {
+ List scenarios = new List(); ;
+
+ List locations = this.SelectedLocationJobs.Select(x => x.Location).ToList();
+ foreach (Location location in locations)
+ {
+ if (location.Scenarios != null)
+ {
+ scenarios.AddRange(location.Scenarios);
+ }
+ }
+
+ return scenarios;
+ }
+
+ ///
+ /// Updates the design calculations.
+ ///
+ public void UpdateDesignCalculations()
+ {
+ if (designCalculations == null)
+ {
+ designCalculations = new List();
+ }
+ else
+ {
+ designCalculations.Clear();
+ }
+ var scenarios = CreateScenarioListForCalculation();
+ foreach (Scenario scenario in scenarios)
+ {
+ if (scenario.CalculationResults != null && scenario.CalculationResults.Count > 0)
+ {
+ designCalculations.AddRange(scenario.CalculationResults);
+ }
+ }
+ DataEventPublisher.DataListModified(designCalculations);
+ }
+
+ [XmlIgnore]
+ [ReadOnly(true)]
+ public List DesignCalculations
+ {
+ get
+ {
+ if (designCalculations == null)
+ {
+ this.UpdateDesignCalculations();
+ }
+
+ return designCalculations;
+ }
+ }
+
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public List SchematizationFactors
+ {
+ get
+ {
+ if (schematizationFactors == null)
+ {
+ schematizationFactors = new List();
+ this.UpdateSchematizationFactors();
+ }
+
+ return schematizationFactors;
+ }
+ }
+
+ public void UpdateSchematizationFactors()
+ {
+ if (schematizationFactors != null)
+ {
+ schematizationFactors.Clear();
+
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ if (locationJob.HasSchematizationFactorResults)
+ {
+ foreach (
+ var rwSchematizationFactorResult in
+ locationJob.LocationResult.SchematizationFactorsResult.SchematizationFactorResults)
+ {
+ schematizationFactors.Add(rwSchematizationFactorResult);
+ }
+ }
+ }
+
+ DataEventPublisher.DataListModified(this.schematizationFactors);
+ }
+ }
+
+ public SchematizationFactorData SchematizationFactorData
+ {
+ get { return schematizationFactorData; }
+ set
+ {
+ DataEventPublisher.BeforeChange(this, "SchematizationFactorData");
+ schematizationFactorData = value;
+ DataEventPublisher.AfterChange(this, "SchematizationFactorData");
+ }
+ }
+
+ public CalculationResult Validate()
+ {
+ try
+ {
+ //Todo validation has to extended, handling the actual messages instead of just CalculationResult too.
+ foreach (Dike dike in this.WaterBoard.Dikes)
+ {
+ dike.Validate();
+ }
+ return CalculationResult.Succeeded;
+ }
+ catch
+ {
+ return CalculationResult.InvalidInputData;
+ }
+ }
+
+ public LocationJob GetLocationJob(Location location)
+ {
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ if (locationJob.Location == location)
+ {
+ return locationJob;
+ }
+ }
+
+ return null;
+ }
+
+ [XmlIgnore]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public List LocationJobs
+ {
+ get
+ {
+ if (jobs.Count == 0)
+ {
+ CompositeJob waterboardJob = this.WaterBoardJob as CompositeJob;
+ foreach (CompositeJob dijkJob in waterboardJob.Jobs)
+ {
+ foreach (LocationJob locationJob in dijkJob.Jobs)
+ {
+ jobs.Add(locationJob);
+ }
+ }
+ }
+
+ return jobs;
+ }
+ }
+
+ public LocationJob GetFirstLocationJobWithDesignResults()
+ {
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ if (locationJob.HasScenarioResults)
+ {
+ return locationJob;
+ }
+ }
+ return null;
+ }
+
+ public LocationJob GetFirstLocationJobWithAssesmentResults()
+ {
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ if (locationJob.HasRWScenarioResults)
+ {
+ return locationJob;
+ }
+ }
+ return null;
+ }
+
+ public LocationJob GetFirstLocationJobWithCalamityResults()
+ {
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ if (locationJob.HasLocationResults)
+ {
+ return locationJob;
+ }
+ }
+ return null;
+ }
+
+ [XmlIgnore]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ [Validate]
+ public List SelectedLocationJobs
+ {
+ get
+ {
+ List selectedLocationJobs = new List();
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ if (locationJob.Run.HasValue && locationJob.Run.Value)
+ {
+ selectedLocationJobs.Add(locationJob);
+ }
+ }
+
+ return selectedLocationJobs;
+ }
+ }
+
+ [Validate]
+ public ValidationResult[] ValidateEnoughLocationJobs()
+ {
+ if (this.SelectedLocationJobs.Count == 0)
+ {
+ return new ValidationResult[]
+ {
+ new ValidationResult(ValidationResultType.Error,
+ LocalizationManager.GetTranslatedText(this, "NoLocationsSelected"),
+ this)
+ };
+ }
+ else
+ {
+ return new ValidationResult[0];
+ }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ [ReadOnly(true)]
+ [Label("Locations")]
+ public List Locations
+ {
+ get { return this.WaterBoard.Locations; }
+ }
+
+ [Browsable(false)]
+ public List DataSources
+ {
+ get { return dataSources; }
+ set { dataSources = value; }
+ }
+
+ [Browsable(false)]
+ public string DataSourceEsriProjection
+ {
+ get { return this.dataSourceEsriProjection; }
+ set { this.dataSourceEsriProjection = value; }
+ }
+
+ public ProgramType ProgramType
+ {
+ // For now, only MStab (= default value) allowed so ReadOnly. Add setter when needed.
+ get { return programType; }
+ }
+
+ ///
+ /// Gets or sets the sensor data.
+ ///
+ ///
+ /// The sensor data.
+ ///
+ public SensorData SensorData
+ {
+ get { return sensorData; }
+ set { sensorData = value; }
+ }
+
+ public EvaluationJob GetEvaluationJob()
+ {
+ EvaluationJob evaluationJob = new EvaluationJob();
+
+ evaluationJob.DikeName = this.WaterBoard.Dikes[0].Name;
+ //evaluationJob.MapForSoilGeometries2D = this.WaterBoard.Dikes[0].MapForSoilGeometries2D;
+ //evaluationJob.SoildatabaseName = this.WaterBoard.Dikes[0].SoilDatabaseName;
+
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ if (locationJob.Run != null && locationJob.Run.Value)
+ {
+ foreach (Dike dike in this.WaterBoard.Dikes)
+ {
+ if (dike.Locations.Contains(locationJob.Location))
+ {
+ dike.UpdateLocation(locationJob.Location);
+ break;
+ }
+ }
+
+ evaluationJob.Locations.Add(locationJob.Location);
+ }
+ }
+
+ return evaluationJob;
+ }
+
+ ///
+ /// Ensures the proper zone safety factors are available for all locations.
+ ///
+ public void EnsureProperZoneSafetyFactors()
+ {
+ foreach (var location in Locations)
+ {
+ location.EnsureProperZoneSafetyFactors();
+ }
+ }
+
+ public void DeleteResults()
+ {
+ LogManager.Messages.Clear();
+ if (waterBoardJob != null && waterBoardJob.Jobs != null)
+ {
+ waterBoardJob.Jobs.Clear();
+ }
+ waterBoardJob = null;
+ if (jobs != null)
+ {
+ jobs.Clear();
+ }
+ if (calculations != null)
+ {
+ calculations.Clear();
+ }
+ if (schematizationFactors != null)
+ {
+ schematizationFactors.Clear();
+ }
+
+ // Delete calculationresults in scenarios
+ var scenarios = CreateScenarioListForDeletion();
+ foreach (Scenario scenario in scenarios)
+ {
+ scenario.ClearResults();
+ scenario.ClearErrors();
+ }
+
+ if (designCalculations != null)
+ {
+ designCalculations.Clear();
+ }
+ }
+
+ private EvaluationJob GetCalculatedEvaluationJob()
+ {
+ EvaluationJob evaluationJob = new EvaluationJob();
+
+ evaluationJob.DikeName = this.WaterBoard.Dikes[0].Name;
+
+ foreach (LocationJob locationJob in this.LocationJobs)
+ {
+ if ((locationJob.Result != JobResult.NoRun || (locationJob.HasRWScenarioResults)) && locationJob.Run != null && locationJob.Run.Value)
+ {
+ foreach (Dike dike in this.WaterBoard.Dikes)
+ {
+ if (dike.Locations.Contains(locationJob.Location))
+ {
+ dike.UpdateLocation(locationJob.Location);
+ break;
+ }
+ }
+
+ evaluationJob.Locations.Add(locationJob.Location);
+ }
+ }
+
+ return evaluationJob;
+ }
+
+ public bool HasResults()
+ {
+ bool hasResults = waterBoard.Dikes.Count > 0 && waterBoardJob != null && waterBoardJob.Jobs.Count > 0;
+ if (hasResults)
+ {
+ EvaluationJob evaluationJob = GetCalculatedEvaluationJob();
+ hasResults = evaluationJob.Locations != null && evaluationJob.Locations.Count > 0;
+ }
+ return hasResults;
+ }
+
+ ///
+ /// Check if design with geometry adaption is allowed
+ ///
+ ///
+ private bool IsDesignWithGeometryAdaptionAllowed()
+ {
+ bool isAdoption = this.DamProjectType == DamProjectType.Design && DamProjectCalculationSpecification.SelectedAnalysisType != AnalysisType.NoAdaption;
+ bool isStabilityOutside = this.DamProjectCalculationSpecification.DamCalculationSpecifications.Any(specification => specification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityOutside);
+ return (!isAdoption || !isStabilityOutside);
+ }
+
+ ///
+ /// Validates the geometry adaption setting.
+ ///
+ ///
+ [Validate]
+ public ValidationResult[] ValidateGeometryAdaptionSetting()
+ {
+ if (!IsDesignWithGeometryAdaptionAllowed())
+ {
+ return new[]{ new ValidationResult(ValidationResultType.Error, LocalizationManager.GetTranslatedText(this, "DesignAndAdaptionNotAllowedForStabilityOutside"),
+ this, "DamCalculationSpecifications", "DamCalculationSpecifications", null)};
+ }
+ else
+ {
+ return new ValidationResult[0];
+ }
+
+ }
+
+ public override bool IsVisible(string property)
+ {
+ switch (property)
+ {
+ case "SensorData": return damProjectType == DamProjectType.DamLiveConfiguration;
+ case "SchematizationFactors": return false;
+ //Bka: for now (release 1.4.1), do not show SchematizationFactors return this.HasResults() && this.DamProjectType == Data.DamProjectType.Assessment;
+ case "Calculations": return this.HasResults() && this.DamProjectType == DamProjectType.Assessment;
+ case "DesignCalculations": return this.HasResults() && this.DamProjectType == DamProjectType.Design;
+ case "DamProjectCalculationSpecification":
+ return damProjectCalculationSpecification.DamCalculationSpecifications.Count > 0;
+ default: return true;
+ }
+ }
+
+ public ICollection GetDomain(string property)
+ {
+ switch (property)
+ {
+ default: return null;
+ }
+ }
+
+ public override string ToString()
+ {
+ return this.WaterBoard != null ? this.WaterBoard.Name : "";
+ }
+
+ public void Dispose()
+ {
+ WaterBoard.Dispose();
+ DamProjectCalculationSpecification.Dispose();
+ }
+
+ public void FillOverallSensorData()
+ {
+ if (sensorData != null)
+ {
+ sensorData.Sensors.Clear();
+ sensorData.SensorGroups.Clear();
+ sensorData.SensorLocations.Clear();
+ }
+ else
+ {
+ sensorData = new SensorData();
+ }
+ foreach (var location in Locations)
+ {
+ var sd = location.SensorData;
+
+ foreach (var sensor in sd.Sensors )
+ {
+ if (sensorData.GetSensorById(sensor.ID) == null)
+ {
+ sensorData.Sensors.Add(sensor);
+ }
+ }
+ if (sensorData.GetGroupById(sd.Group.ID) == null && sd.Group.ID >= 0)
+ {
+ sd.Group.PickSensors = sensorData.Sensors;
+ sensorData.SensorGroups.Add(sd.Group);
+ }
+ if (sensorData.GetSensorLocationByLocationName(sd.LocationName) == null)
+ {
+ sensorData.SensorLocations.Add(sd);
+ }
+ }
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile1D.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile1D.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile1D.cs (revision 274)
@@ -0,0 +1,659 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Language;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Interface for providing the 1D Soil Profile
+ ///
+ public interface ISoilProfileProvider
+ {
+ ///
+ /// Gets the soil profile.
+ ///
+ ///
+ /// The soil profile.
+ ///
+ SoilProfile1D SoilProfile { get; }
+ }
+
+ ///
+ /// 1D Soil Profile Object
+ ///
+ public class SoilProfile1D : SoilProfile
+ {
+ private const double defaultBottomLayerHeight = 20.0;
+
+ private readonly DelegatedList layers = new DelegatedList();
+ private double bottomLevel = double.NaN;
+
+ ///
+ /// Default constructor
+ ///
+ public SoilProfile1D()
+ {
+ Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSoilProfile1D");
+ layers.AddMethod = AddLayer;
+ }
+
+ ///
+ /// Gets the soil layer collection for this profile
+ ///
+ public IList Layers
+ {
+ get
+ {
+ return layers;
+ }
+ }
+
+ ///
+ /// Gets the number of layers.
+ ///
+ ///
+ /// The layer count.
+ ///
+ [XmlIgnore]
+ public int LayerCount
+ {
+ get
+ {
+ return layers.Count;
+ }
+ }
+
+ ///
+ /// Gets or sets the bottom level.
+ ///
+ ///
+ /// The bottom level.
+ ///
+ public double BottomLevel
+ {
+ get
+ {
+ if (double.IsNaN(bottomLevel) && layers.Count > 0)
+ {
+ bottomLevel = Layers.Last().TopLevel - defaultBottomLayerHeight;
+ }
+
+ return bottomLevel;
+ }
+ set
+ {
+ if (double.IsNaN(bottomLevel) || (Math.Abs(value - bottomLevel) > GeometryConstants.Accuracy))
+ {
+ bottomLevel = value;
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the top level.
+ ///
+ ///
+ /// The top level.
+ ///
+ public double TopLevel
+ {
+ get
+ {
+ return layers.Any() ? layers.First().TopLevel : BottomLevel;
+ }
+ }
+
+ ///
+ /// The highest aquifer layer, can be null if not aquifer is present
+ ///
+ [Validate]
+ public SoilLayer1D TopAquiferLayer
+ {
+ get
+ {
+ IList sortedLayers = Layers.OrderByDescending(l => l.TopLevel).ToList();
+ SoilLayer1D aquiferLayer = null;
+
+ // Search the highest aquifer layer
+ for (int layerIndex = 0; layerIndex < sortedLayers.Count; layerIndex++)
+ {
+ var layer = sortedLayers[layerIndex];
+ if (IsAquiferLayer(layer))
+ {
+ aquiferLayer = layer;
+ break;
+ }
+ }
+ return aquiferLayer;
+ }
+ }
+
+ ///
+ /// Gets the toppest aquifer layer of the deepest cluster of aquifers
+ ///
+ ///
+ /// The toppest aquifer layer in the deepest cluster of aquifers
+ ///
+ public SoilLayer1D BottomAquiferLayer
+ {
+ get
+ {
+ IList sortedLayers = Layers.OrderBy(l => l.TopLevel).ToList();
+ SoilLayer1D aquiferLayer = null;
+ int aquiferIndex = -1;
+
+ // Search deepest aquifer layer
+ for (int layerIndex = 0; layerIndex < sortedLayers.Count; layerIndex++)
+ {
+ SoilLayer1D layer = sortedLayers[layerIndex];
+ if (IsAquiferLayer(layer))
+ {
+ aquiferIndex = layerIndex;
+ aquiferLayer = layer;
+ break;
+ }
+ }
+
+ // aquifer may consists of more then 1 connected (aquifer) layers
+ // Search all layers above the first found aquifer to find top aquifer layer
+ if (aquiferIndex >= 0)
+ {
+ for (int layerIndex = aquiferIndex + 1; layerIndex < sortedLayers.Count; layerIndex++)
+ {
+ var layer = sortedLayers[layerIndex];
+ if (IsAquiferLayer(layer))
+ {
+ aquiferLayer = layer;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ return aquiferLayer;
+ }
+ }
+
+ ///
+ /// Gets the highest aquifer in the highest cluster of in-between aquifers.
+ /// The top layer of a cluster of in-between aquifer can't be the highest layer of the soil profile.
+ ///
+ ///
+ /// The highest aquifer in the highest in-between cluster of aquifers
+ ///
+ public SoilLayer1D InBetweenAquiferLayer
+ {
+ get
+ {
+ IList sortedLayers = Layers.OrderByDescending(l => l.TopLevel).ToList();
+ SoilLayer1D aquiferLayer = null;
+
+ // Search the highest aquifer layer with an aquitard above
+ for (int layerIndex = 1; layerIndex < sortedLayers.Count; layerIndex++)
+ {
+ var previousLayer = sortedLayers[layerIndex - 1];
+ var layer = sortedLayers[layerIndex];
+ if (IsAquiferLayer(layer) && !IsAquiferLayer(previousLayer))
+ {
+ aquiferLayer = layer;
+ break;
+ }
+ }
+
+ // If highest aquifer layer is bottom aquifer layer, there is no in between aquiferlayer
+ if (aquiferLayer == BottomAquiferLayer)
+ {
+ aquiferLayer = null;
+ }
+ return aquiferLayer;
+ }
+ }
+
+ ///
+ /// Gets the lowest layer in the highest cluster of in-between aquifers
+ ///
+ ///
+ /// The lowest layer in the highest cluster of in-between aquifers
+ ///
+ public SoilLayer1D BottomLayerOfInBetweenAquiferCluster
+ {
+ get
+ {
+ IList sortedLayers = Layers.OrderByDescending(l => l.TopLevel).ToList();
+ SoilLayer1D highestAquiferLayer = null;
+ SoilLayer1D aquiferLayer = null;
+ int indexHighestAquifer = -1;
+
+ // Search the index of the highest aquifer layer
+ for (int layerIndex = 1; layerIndex < sortedLayers.Count; layerIndex++)
+ {
+ var previousLayer = sortedLayers[layerIndex - 1];
+ var layer = sortedLayers[layerIndex];
+ if (IsAquiferLayer(layer) && !IsAquiferLayer(previousLayer))
+ {
+ highestAquiferLayer = layer;
+ indexHighestAquifer = layerIndex;
+ break;
+ }
+ }
+
+ // If highest aquifer layer is bottom aquifer layer, there is no in between aquiferlayer
+ if (highestAquiferLayer == BottomAquiferLayer)
+ {
+ return null;
+ }
+
+ // in-between aquifers cluster may consists of more then 1 connected (aquifer) layers.
+ // Search all layers below the found highest aquifer to find bottom aquifer layer.
+ if (indexHighestAquifer >= 0)
+ {
+ for (int layerIndex = indexHighestAquifer; layerIndex < sortedLayers.Count; layerIndex++)
+ {
+ var layer = sortedLayers[layerIndex];
+
+ if (IsAquiferLayer(layer))
+ {
+ aquiferLayer = layer;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ return aquiferLayer;
+ }
+ }
+
+ ///
+ /// Gets (calculates) the height for a given layer in the profile
+ ///
+ /// The layer to process
+ /// The height
+ public double GetLayerHeight(SoilLayer1D soilLayer)
+ {
+ var layerIndex = layers.IndexOf(soilLayer);
+ var soilLayerBelow = (layerIndex < layers.Count - 1) ? layers[layerIndex + 1] : null;
+ var levelBelow = (soilLayerBelow != null) ? soilLayerBelow.TopLevel : BottomLevel;
+ return soilLayer.TopLevel - levelBelow;
+ }
+
+ ///
+ /// Validates this instance (using validator mechanism).
+ ///
+ ///
+ [Validate]
+ public ValidationResult[] Validate()
+ {
+ SoilLayer1D erroneousLayer;
+
+ if (LayerCount == 0)
+ {
+ var error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileWithoutLayers"), Name);
+ return new[]
+ {
+ new ValidationResult(ValidationResultType.Error,
+ error, "", this)
+ };
+ }
+
+ if (!IsStrictlyDescending(out erroneousLayer))
+ {
+ var error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileLayersNotDescending"),
+ Name, erroneousLayer.Name);
+ return new[]
+ {
+ new ValidationResult(ValidationResultType.Error,
+ error, "", this)
+ };
+ }
+
+ if (HasInvalidThicknessLayers(out erroneousLayer))
+ {
+ var error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileInvalidLayerThickness"),
+ Name, erroneousLayer.Name);
+ return new[]
+ {
+ new ValidationResult(ValidationResultType.Error,
+ error, "", this)
+ };
+ }
+
+ if (HasLayersWithoutSoil(out erroneousLayer))
+ {
+ var error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileLayerWithoutSoil"),
+ Name, erroneousLayer.Name);
+ return new[]
+ {
+ new ValidationResult(ValidationResultType.Error,
+ error, "", this)
+ };
+ }
+ return new ValidationResult[0];
+ }
+
+ ///
+ /// Gets the aquifer layers.
+ ///
+ /// list of Aquifer layers
+ public IList GetAquiferLayers()
+ {
+ return Layers.Where(IsAquiferLayer).OrderBy(l => l.TopLevel).ToList();
+ }
+
+ ///
+ /// Gets the bottom level.
+ ///
+ /// The soil layer.
+ /// Bottom level
+ public double GetBottomLevel(SoilLayer1D soilLayer)
+ {
+ var layerBelow = GetLayerBelow(soilLayer);
+
+ return layerBelow != null ? layerBelow.TopLevel : BottomLevel;
+ }
+
+ ///
+ /// Ares the layers ordered descending.
+ ///
+ ///
+ /// true if all layers are ordered descending; otherwise, false.
+ ///
+ private bool AreLayersOrderedByDescending()
+ {
+ // check for empty list
+ if (Layers.Count <= 1)
+ {
+ return true;
+ }
+
+ var current = Layers[0];
+ for (int i = 1; i < Layers.Count; ++i)
+ {
+ var previous = current;
+ current = Layers[i];
+
+ if (current.TopLevel > previous.TopLevel)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// Determines whether the layers are strictly ordered in descending order.
+ /// If erroneous layer is found, false is returned and the layer
+ /// is stored in the parameter
+ ///
+ /// The erroneous layer.
+ /// true if the layers are strictly ordered in descending order; otherwise, false.
+ private bool IsStrictlyDescending(out SoilLayer1D erroneousLayer)
+ {
+ for (int i = 1; i < layers.Count; i++)
+ {
+ if (layers[i].TopLevel > layers[i - 1].TopLevel)
+ {
+ erroneousLayer = layers[i];
+ return false;
+ }
+ }
+
+ erroneousLayer = null;
+ return true;
+ }
+
+ ///
+ /// Determines whether there are layers with invalid thickness.
+ ///
+ /// The erroneous layer.
+ /// True when a layer with invalid thickness exists
+ private bool HasInvalidThicknessLayers(out SoilLayer1D erroneousLayer)
+ {
+ for (int i = 1; i < layers.Count; i++)
+ {
+ if (layers[i].TopLevel >= layers[i - 1].TopLevel)
+ {
+ erroneousLayer = layers[i];
+ return true;
+ }
+ }
+ // check bottom layer using bottom of profile
+ if (layers.Count > 0 && layers[layers.Count - 1].TopLevel <= BottomLevel)
+ {
+ erroneousLayer = layers[layers.Count - 1];
+ return true;
+ }
+ erroneousLayer = null;
+ return false;
+ }
+
+ ///
+ /// Determines whether there are layers without soil.
+ ///
+ /// The erroneous layer.
+ /// true when a layer without soil is found
+ private bool HasLayersWithoutSoil(out SoilLayer1D erroneousLayer)
+ {
+ for (int i = 0; i < layers.Count; i++)
+ {
+ if (layers[i].Soil == null)
+ {
+ erroneousLayer = layers[i];
+ return true;
+ }
+ }
+ erroneousLayer = null;
+ return false;
+ }
+
+ ///
+ /// Gets the layer by inset offset, seen from the given layer plus the given offset.
+ ///
+ /// The layer.
+ /// The offset.
+ /// the found layer, if no layer found, null
+ private SoilLayer1D GetLayerByInsetOffset(SoilLayer1D layer, int offset)
+ {
+ // only works if list is sorted
+ if (!AreLayersOrderedByDescending())
+ {
+ layers.Sort();
+ }
+
+ int index = GetLayerIndexAt(layer);
+
+ // was the layer found?
+ if (index < 0 || index >= layers.Count)
+ {
+ return null;
+ }
+
+ // is there a layer at the specified offset?
+ int requestedIndex = index + offset;
+ if (requestedIndex < 0 || requestedIndex >= layers.Count)
+ {
+ return null;
+ }
+
+ // return the valid layer
+ return layers[requestedIndex];
+ }
+
+ ///
+ /// Gets the layer below the given layer.
+ ///
+ /// The given layer.
+ /// The found layer
+ public SoilLayer1D GetLayerBelow(SoilLayer1D layer)
+ {
+ return GetLayerByInsetOffset(layer, 1);
+ }
+
+ ///
+ /// Gets the layer index of the given layer.
+ ///
+ /// The layer.
+ /// The index, -1 if not found
+ private int GetLayerIndexAt(SoilLayer1D layer)
+ {
+ if (layer == null)
+ {
+ return -1;
+ }
+
+ for (int i = 0; i < layers.Count; ++i)
+ {
+ if (layers[i] == layer)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ ///
+ /// Gets the top level of highest aquifer.
+ ///
+ ///
+ public double GetTopLevelOfHighestAquifer()
+ {
+ double topLevel;
+ if (InBetweenAquiferLayer != null)
+ {
+ topLevel = InBetweenAquiferLayer.TopLevel;
+ }
+ else
+ {
+ topLevel = BottomAquiferLayer.TopLevel;
+ }
+ return topLevel;
+ }
+
+ ///
+ /// Gets the total soil pressure, including the eventual free water on surface
+ ///
+ /// The level for wich the total pressure is calculated
+ /// The phreatic level
+ /// Unit weight of the water
+ /// The soil pressure
+ public double GetTotalPressure(double z, double phreaticLevel, double unitWeightWater)
+ {
+ double pressure = 0;
+
+ // see if free water is at surface
+ double surfaceLevel = Layers[0].TopLevel;
+ if (z > surfaceLevel)
+ {
+ return Math.Max(0, (phreaticLevel - z)*unitWeightWater);
+ }
+
+ if (phreaticLevel > surfaceLevel)
+ {
+ if (z < phreaticLevel)
+ {
+ pressure += (phreaticLevel - Math.Max(Layers[0].TopLevel, z))*unitWeightWater;
+ }
+ }
+
+ foreach (var layer in Layers)
+ {
+ if (layer.Height > 0 && layer.Soil != null)
+ {
+ if (z >= layer.TopLevel)
+ {
+ continue;
+ }
+ if (z <= layer.BottomLevel)
+ {
+ if (phreaticLevel <= layer.BottomLevel)
+ {
+ pressure += layer.Height*layer.Soil.AbovePhreaticLevel;
+ }
+ else if (phreaticLevel >= layer.TopLevel)
+ {
+ pressure += layer.Height*layer.Soil.BelowPhreaticLevel;
+ }
+ else
+ {
+ pressure += (phreaticLevel - layer.BottomLevel)*layer.Soil.BelowPhreaticLevel;
+ pressure += (layer.TopLevel - phreaticLevel)*layer.Soil.AbovePhreaticLevel;
+ }
+ }
+ else
+ {
+ if (phreaticLevel <= z)
+ {
+ pressure += (layer.TopLevel - z)*layer.Soil.AbovePhreaticLevel;
+ }
+ else if (phreaticLevel >= layer.TopLevel)
+ {
+ pressure += (layer.TopLevel - z)*layer.Soil.BelowPhreaticLevel;
+ }
+ else
+ {
+ pressure += (layer.TopLevel - phreaticLevel)*layer.Soil.AbovePhreaticLevel;
+ pressure += (phreaticLevel - z)*layer.Soil.BelowPhreaticLevel;
+ }
+ }
+ }
+ }
+
+ return pressure;
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ private void AddLayer(SoilLayer1D layer)
+ {
+ layer.SoilProfile = this;
+ }
+
+ ///
+ /// Determines whether the specified layer is an aquifer layer.
+ ///
+ /// The layer.
+ /// true if layer is aquifer layer; otherwise, false.
+ private static bool IsAquiferLayer(SoilLayer1D layer)
+ {
+ return (layer.IsAquifer);
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (revision 274)
@@ -0,0 +1,72 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}
+ Library
+ Properties
+ Deltares.DamEngine.Calculators
+ Deltares.DamEngine.Calculators
+ v4.5
+ 512
+
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\x86\Release\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {b7a49c1a-1c91-4d72-aba9-9fbac2509d8e}
+ Deltares.DamEngine.Data
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamFailureMechanismeCalculationSpecification.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamFailureMechanismeCalculationSpecification.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamFailureMechanismeCalculationSpecification.cs (revision 274)
@@ -0,0 +1,286 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2010 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 18-05-2010
+//
+// data class for specifying one single calculation
+// data class for xml file creator for DGSMStabDam.dll
+// Note: this is a single class with dual purpose; maybe refactor
+// Pull out the XML specific things into DamMStabInput
+//
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Xml.Serialization;
+
+namespace Deltares.DamEngine.Data.General
+{
+ ///
+ ///
+ ///
+ public class DamFailureMechanismeCalculationSpecification: IDomain, IVisibleEnabled
+ {
+ 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();
+ }
+
+ [Browsable(false)]
+ [Validate]
+ public FailureMechanismeParamatersMStab FailureMechanismeParamatersMStab
+ {
+ get { return failureMechanismeParamatersMStab; }
+ set { failureMechanismeParamatersMStab = value; }
+ }
+
+ [Label("Failure mechanism")]
+ [PropertyOrder(1, 0)]
+ public FailureMechanismSystemType FailureMechanismSystemType
+ {
+ get { return failureMechanismSystemType; }
+ set
+ {
+ if (failureMechanismSystemType != value)
+ {
+ DataEventPublisher.BeforeChange(this, "FailureMechanismSystemType");
+ 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;
+ }
+ 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;
+ }
+ DataEventPublisher.AfterChange(this, "FailureMechanismSystemType");
+ }
+ }
+ }
+
+ [Browsable(false)]
+ public PipingModelType PipingModelType
+ {
+ get { return pipingModelType; }
+ set
+ {
+ pipingModelType = value;
+ if (failureMechanismSystemType == FailureMechanismSystemType.Piping)
+ {
+ CalculationModel = pipingModelType;
+ }
+ }
+ }
+
+ [Browsable(false)]
+ public static DamProjectType DamProjectType
+ {
+ get { return damProjectType; }
+ set { damProjectType = value; }
+ }
+
+ [Browsable(false)]
+ 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]
+ [Label("Model")]
+ [PropertyOrder(1, 1)]
+ public Enum CalculationModel
+ {
+ get { return calculationModel; }
+ set
+ {
+ DataEventPublisher.BeforeChange(this, "CalculationModel");
+ calculationModel = value;
+ if (value is PipingModelType)
+ {
+ pipingModelType = (PipingModelType) value;
+ }
+ else
+ {
+ failureMechanismeParamatersMStab.MStabParameters.Model = (MStabModelType)value;
+ }
+ DataEventPublisher.AfterChange(this, "CalculationModel");
+ }
+ }
+
+ [Browsable(false)]
+ public MStabModelType StabilityModelType
+ {
+ get { return failureMechanismeParamatersMStab.MStabParameters.Model; }
+ set
+ {
+ failureMechanismeParamatersMStab.MStabParameters.Model = value;
+ if (failureMechanismSystemType != FailureMechanismSystemType.Piping)
+ {
+ CalculationModel = value;
+ }
+ }
+ }
+
+ [Browsable(false)]
+ 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;
+ }
+
+ public ICollection GetDomain(string property)
+ {
+ switch (property)
+ {
+ case "CalculationModel":
+ return (ConfigurationManager.Instance.GetAvailableMechanismModels(StabilityKernelType, DamProjectType,
+ ProbabilisticType, failureMechanismSystemType));
+
+ case "PipingModelType":
+ return (ConfigurationManager.Instance.GetAvailableMechanismModels(StabilityKernelType, DamProjectType,
+ ProbabilisticType, FailureMechanismSystemType.Piping));
+
+ case "FailureMechanismSystemType":
+ return (ConfigurationManager.Instance.GetAvailableFailureMechanisms(StabilityKernelType, DamProjectType,
+ ProbabilisticType));
+ case "StabilityKernelType":
+ return (ConfigurationManager.Instance.GetAvailableFailureMechanisms(StabilityKernelType, DamProjectType,
+ ProbabilisticType));
+ default: return null;
+ }
+ }
+
+
+ public bool IsEnabled(string property)
+ {
+ return true;
+ }
+
+ public bool IsVisible(string property)
+ {
+ switch (property)
+ {
+ case "FailureMechanismeParamatersMStab":
+ switch (this.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside: return true;
+ case FailureMechanismSystemType.StabilityOutside: return true;
+ case FailureMechanismSystemType.HorizontalBalance: return false;
+ case FailureMechanismSystemType.Piping: return false;
+ default: return true;
+ }
+ default: return true;
+ }
+ }
+
+ ///
+ /// 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/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/TranslationAttribute.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/TranslationAttribute.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/TranslationAttribute.cs (revision 274)
@@ -0,0 +1,57 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard.Language
+{
+ ///
+ /// This attribute defines a custom identifier as override when indexing translations files to retrieve translated text.
+ ///
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Class)]
+ public class TranslationAttribute : Attribute
+ {
+ private readonly string id;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The identifier.
+ public TranslationAttribute(string id)
+ {
+ this.id = id;
+ }
+
+ ///
+ /// Gets the identifier.
+ ///
+ ///
+ /// The identifier.
+ ///
+ public string Id
+ {
+ get
+ {
+ return id;
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryPointString.cs (revision 274)
@@ -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)
+ ///
+ ///
+ ///
+ private 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/branches/Initial Source/Deltares.DamEngine.Data/Standard/VirtualList.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/VirtualList.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/VirtualList.cs (revision 274)
@@ -0,0 +1,408 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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;
+
+namespace Deltares.DamEngine.Data.Standard
+{
+ ///
+ /// Extends the standard List<T> class with delegates which are called on adding or removing items
+ ///
+ /// The generic type to create the list for
+ ///
+ ///
+ ///
+ public class VirtualList : IList, ISortableList, IList where T : class
+ {
+ private readonly List internalList = new List();
+
+ #region List Overrides
+
+ ///
+ /// Gets or sets the element at the specified index.
+ ///
+ /// The index.
+ ///
+ public virtual T this[int index]
+ {
+ get
+ {
+ return internalList[index];
+ }
+ set
+ {
+ internalList[index] = value;
+ }
+ }
+
+ ///
+ /// Gets the number of elements contained in the .
+ ///
+ public virtual int Count
+ {
+ get
+ {
+ return internalList.Count;
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether the is read-only.
+ ///
+ public bool IsReadOnly
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Adds the range.
+ ///
+ /// The collection.
+ public virtual void AddRange(IEnumerable collection)
+ {
+ internalList.AddRange(collection);
+ }
+
+ ///
+ /// To the array.
+ ///
+ ///
+ public virtual T[] ToArray()
+ {
+ return internalList.ToArray();
+ }
+
+ ///
+ /// Adds an item to the .
+ ///
+ /// The object to add to the .
+ public virtual void Add(T item)
+ {
+ internalList.Add(item);
+ }
+
+ ///
+ /// Removes all items from the .
+ ///
+ public virtual void Clear()
+ {
+ internalList.Clear();
+ internalList.Capacity = 0;
+ }
+
+ ///
+ /// Determines whether the contains a specific value.
+ ///
+ /// The object to locate in the .
+ ///
+ /// true if is found in the ; otherwise, false.
+ ///
+ public virtual bool Contains(T item)
+ {
+ return internalList.Contains(item);
+ }
+
+ ///
+ /// Copies to.
+ ///
+ /// The array.
+ /// Index of the array.
+ public virtual void CopyTo(T[] array, int arrayIndex)
+ {
+ internalList.CopyTo(array, arrayIndex);
+ }
+
+ ///
+ /// 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 virtual bool Remove(T item)
+ {
+ return internalList.Remove(item);
+ }
+
+ ///
+ /// 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 virtual int IndexOf(T item)
+ {
+ return internalList.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 virtual void Insert(int index, T item)
+ {
+ internalList.Insert(index, item);
+ }
+
+ ///
+ /// Removes the item at the specified index.
+ ///
+ /// The zero-based index of the item to remove.
+ public virtual void RemoveAt(int index)
+ {
+ internalList.RemoveAt(index);
+ }
+
+ ///
+ /// Sorts this instance.
+ ///
+ public virtual void Sort()
+ {
+ internalList.Sort();
+ }
+
+ ///
+ /// Reverses this instance.
+ ///
+ public virtual void Reverse()
+ {
+ internalList.Reverse();
+ }
+
+ #endregion
+
+ ///
+ /// 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 virtual IEnumerator GetEnumerator()
+ {
+ return internalList.GetEnumerator();
+ }
+
+ #region IList Members
+
+ ///
+ /// Gets a value indicating whether the has a fixed size.
+ ///
+ bool IList.IsFixedSize
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether the is read-only.
+ ///
+ bool IList.IsReadOnly
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Gets or sets the element at the specified index.
+ ///
+ /// The index.
+ ///
+ object IList.this[int index]
+ {
+ get
+ {
+ return this[index];
+ }
+ set
+ {
+ ThrowIfWrongType(value);
+ this[index] = (T) 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,
+ ///
+ int IList.Add(object value)
+ {
+ ThrowIfWrongType(value);
+ Add((T) value);
+ return Count - 1;
+ }
+
+ ///
+ /// Removes all items from the .
+ ///
+ void IList.Clear()
+ {
+ Clear();
+ }
+
+ ///
+ /// Determines whether the contains a specific value.
+ ///
+ /// The object to locate in the .
+ ///
+ /// true if the is found in the ; otherwise, false.
+ ///
+ bool IList.Contains(object value)
+ {
+ if (!(value is T))
+ {
+ return false;
+ }
+
+ return Contains((T) value);
+ }
+
+ ///
+ /// 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.
+ ///
+ int IList.IndexOf(object value)
+ {
+ if (!(value is T))
+ {
+ return -1;
+ }
+
+ return IndexOf((T) 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 .
+ void IList.Insert(int index, object value)
+ {
+ ThrowIfWrongType(value);
+ Insert(index, (T) value);
+ }
+
+ ///
+ /// Removes the first occurrence of a specific object from the .
+ ///
+ /// The object to remove from the .
+ void IList.Remove(object value)
+ {
+ if (value is T)
+ {
+ Remove((T) value);
+ }
+ }
+
+ ///
+ /// Removes the item at the specified index.
+ ///
+ /// The zero-based index of the item to remove.
+ void IList.RemoveAt(int index)
+ {
+ RemoveAt(index);
+ }
+
+ #endregion
+
+ #region ICollection Members
+
+ ///
+ /// Gets the number of elements contained in the .
+ ///
+ int ICollection.Count
+ {
+ get
+ {
+ return Count;
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether access to the is synchronized (thread safe).
+ ///
+ bool ICollection.IsSynchronized
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Gets an object that can be used to synchronize access to the .
+ ///
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ ///
+ /// 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.
+ void ICollection.CopyTo(Array array, int index)
+ {
+ Array.Copy(internalList.ToArray(), 0, array, index, internalList.Count);
+ }
+
+ #endregion
+
+ private void ThrowIfWrongType(object item)
+ {
+ if (!(item is T))
+ {
+ throw new InvalidCastException();
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Properties/AssemblyInfo.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Properties/AssemblyInfo.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Properties/AssemblyInfo.cs (revision 274)
@@ -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/branches/Initial Source/Deltares.DamEngine.Data/General/LocationJob.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/LocationJob.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/LocationJob.cs (revision 274)
@@ -0,0 +1,647 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2009 Deltares. All rights reserved.
+//
+// Rob Brinkman
+// rob.brinkman@deltares.nl
+// 16-2-2011
+// n.a.
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Xml.Serialization;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Data.Design;
+using Deltares.DamEngine.Data.Standard.Calculation;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public interface ILocationJob
+ {
+ Location Location { get; }
+ IEnumerable RWScenarioResults { get; }
+ bool HasRWScenarioResults { get; }
+ }
+
+ public class LocationJob : DamJob, ILocationJob
+ {
+ private TimeSerie waterLevelTimeSerie = new TimeSerie();
+ private LocationResult locationResult = new LocationResult();
+
+ private static ScenarioType currentScenarioType = ScenarioType.Scenario01;
+ private static string currentProfileName = "";
+ private static string currentScenarioName = "";
+ private static string currentCalculation = "";
+ private static DateTime currentTime = DateTime.Today;
+ private static DamProjectType damProjectType = DamProjectType.Calamity;
+ private static ProbabilisticType probabilisticType = ProbabilisticType.Deterministic;
+
+ private double designRequiredFactor = 0.0;
+
+ public LocationJob()
+ {
+ }
+
+ public LocationJob(object subject)
+ : base(subject)
+ {
+ }
+
+ ///
+ /// TODO: what todo when location is null?
+ ///
+ public double XRd { get { return this.Location == null ? 0 : this.Location.XRd; } }
+ public double YRd { get { return this.Location == null ? 0 : this.Location.YRd; } }
+
+ [XmlIgnore]
+ [Validate]
+ public Location Location
+ {
+ get
+ {
+ return this.Subject as Location;
+ }
+ set
+ {
+ this.Subject = value;
+ }
+ }
+
+ public TimeSerie WaterLevelTimeSerie
+ {
+ get { return waterLevelTimeSerie; }
+ set
+ {
+ DataEventPublisher.BeforeChange(this, "WaterLevelTimeSerie");
+ waterLevelTimeSerie = value;
+ DataEventPublisher.AfterChange(this, "WaterLevelTimeSerie");
+ }
+ }
+
+ [XmlOldName("ScenarioResults")]
+ public virtual IEnumerable RWScenarioResults
+ {
+ get
+ {
+ return !this.HasRWScenarioResults ?
+ new List() : this.locationResult.RWScenariosResult.RWScenarioResults;
+ }
+ }
+
+ public virtual IEnumerable SchematizationFactorResults
+ {
+ get
+ {
+ return !this.HasSchematizationFactorResults ?
+ new List() : this.locationResult.SchematizationFactorsResult.SchematizationFactorResults;
+ }
+ }
+
+ public bool HasRWScenarioResults
+ {
+ get { return this.locationResult != null && this.locationResult.RWScenariosResult != null &&
+ this.locationResult.RWScenariosResult.RWScenarioResults.Any();
+ }
+ }
+
+ public bool HasSchematizationFactorResults
+ {
+ get { return this.locationResult != null && this.locationResult.SchematizationFactorsResult != null; }
+ }
+
+ public virtual LocationResult LocationResult
+ {
+ get { return locationResult; }
+ set
+ {
+ DataEventPublisher.BeforeChange(this, "LocationResult");
+ locationResult = value;
+ DataEventPublisher.AfterChange(this, "LocationResult");
+ }
+ }
+
+ private bool HasUsableStabilityTimeSerieEntries()
+ {
+ var res = false;
+ foreach (var timeSerieEntry in locationResult.StabilityTimeSerie.Entries)
+ {
+ if (timeSerieEntry.Value != Double.NaN)
+ {
+ res = true;
+ break;
+ }
+ }
+ return res;
+ }
+
+ public bool HasLocationResults
+ {
+ get
+ {
+ if (locationResult == null)
+ return false;
+ return ((locationResult.PipingTimeSerie != null && locationResult.PipingTimeSerie.Entries.Count > 0) ||
+ (locationResult.StabilityTimeSerie != null &&
+ locationResult.StabilityTimeSerie.Entries.Count > 0 && HasUsableStabilityTimeSerieEntries()));
+ }
+ }
+
+ public LocationResult GetLocationResultWithStabilityTimeSerie(string locationName)
+ {
+ LocationResult result = null;
+ if (locationResult != null && locationResult.StabilityTimeSerie != null &&
+ locationResult.StabilityTimeSerie.LocationId == locationName &&
+ locationResult.StabilityTimeSerie.Entries != null && locationResult.StabilityTimeSerie.Entries.Count > 1)
+ {
+ result = locationResult;
+ }
+ return result;
+ }
+
+ public LocationResult GetFirstLocationResultWithStabilityTimeSerie()
+ {
+ LocationResult result = null;
+ if (locationResult != null && locationResult.StabilityTimeSerie != null &&
+ locationResult.StabilityTimeSerie.Entries != null && locationResult.StabilityTimeSerie.Entries.Count > 1)
+ {
+ result = locationResult;
+ }
+ return result;
+ }
+
+ public RWScenarioProfileResult GetAssesmentResultByProfile(ScenarioType scenarioType, string profileName)
+ {
+ if (this.HasRWScenarioResults)
+ {
+ RWScenarioResult scenarioResult = this.LocationResult.RWScenariosResult.GetScenarioResult(scenarioType);
+ if (scenarioResult != null)
+ {
+ foreach (var res in scenarioResult.RWScenarioProfileResults)
+ {
+ if (res.SoilProfileName == profileName)
+ return res;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public CsvExportData GetFirstDesignResult()
+ {
+ if (this.HasScenarioResults)
+ {
+ Scenario scenario = Location.Scenarios[0];
+ if (scenario != null && scenario.CalculationResults.Count > 0)
+ {
+ return scenario.CalculationResults[0];
+ }
+ }
+ return null;
+ }
+
+ public CsvExportData GetDesignResultByProfileScenarioAndCalculationName(string profileName, string scenarioName,
+ string calculationName)
+ {
+ if (this.HasScenarioResults)
+ {
+ foreach (var scenario in Location.Scenarios)
+ {
+ foreach (var calculationResult in scenario.CalculationResults)
+ {
+ if (calculationResult.ProfileName == profileName &&
+ calculationResult.ScenarioName == scenarioName &&
+ calculationResult.Calculation == calculationName)
+ return calculationResult;
+ }
+ }
+ }
+ return null;
+ }
+ ///
+ /// Return the result of the profile with highest probability of occurrence
+ ///
+ ///
+ ///
+ public RWScenarioProfileResult GetRWScenarioResultOfProfileWithHighestProbablilityOfOccurrence(ScenarioType scenarioType)
+ {
+ if (this.HasRWScenarioResults)
+ {
+ RWScenarioResult scenarioResult = this.LocationResult.RWScenariosResult.GetScenarioResult(scenarioType);
+ if (scenarioResult != null && scenarioResult.RWScenarioProfileResults.Count > 0)
+ {
+ RWScenarioProfileResult rwScenarioProfileResult = scenarioResult.RWScenarioProfileResults[0];
+ for (int i = 1; i < scenarioResult.RWScenarioProfileResults.Count; i++)
+ {
+ if (scenarioResult.RWScenarioProfileResults[i].SoilProfileProbability > rwScenarioProfileResult.SoilProfileProbability)
+ {
+ rwScenarioProfileResult = scenarioResult.RWScenarioProfileResults[i];
+ }
+ }
+ return rwScenarioProfileResult;
+ }
+ }
+ return null;
+ }
+
+ ///
+ /// Return result with the lowest safetyfactor
+ ///
+ ///
+ ///
+ public RWScenarioProfileResult GetRWScenarioResultWithLowestSafetyFactor(ScenarioType scenarioType)
+ {
+ if (this.HasRWScenarioResults)
+ {
+ RWScenarioResult scenarioResult = this.LocationResult.RWScenariosResult.GetScenarioResult(scenarioType);
+ if (scenarioResult != null && scenarioResult.RWScenarioProfileResults.Count > 0)
+ {
+ RWScenarioProfileResult rwScenarioProfileResult = scenarioResult.RWScenarioProfileResults[0];
+ for (int i = 1; i < scenarioResult.RWScenarioProfileResults.Count; i++)
+ {
+ if (scenarioResult.RWScenarioProfileResults[i].SafetyFactor < rwScenarioProfileResult.SafetyFactor)
+ {
+ rwScenarioProfileResult = scenarioResult.RWScenarioProfileResults[i];
+ }
+ }
+ return rwScenarioProfileResult;
+ }
+ }
+ return null;
+ }
+
+ public bool HasScenarioResults
+ {
+ get
+ {
+ List scenarios = Location.Scenarios;
+ foreach (var scenario in scenarios)
+ {
+ foreach (var calculationResult in scenario.CalculationResults)
+ {
+ if (ProbabilisticType == ProbabilisticType.Deterministic)
+ {
+ if ((calculationResult.SafetyFactor != null) || (calculationResult.CalculationResult == CalculationResult.UnexpectedError) )
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if (calculationResult.FailureProbability != null)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ ///
+ /// Get lowest safetyfactor of all scenarios
+ ///
+ ///
+ private double GetLowestRealSafetyFactorFromScenarios()
+ {
+ var res = double.MaxValue;
+ List scenarios = Location.Scenarios;
+ foreach (var scenario in scenarios)
+ {
+ foreach (var calculationResult in scenario.CalculationResults)
+ {
+ if (calculationResult.CalculationResult == CalculationResult.UnexpectedError)
+ {
+ res = -1;
+ }
+ if (calculationResult.SafetyFactor != null)
+ {
+ if (calculationResult.SafetyFactor.Value < res)
+ {
+ res = calculationResult.SafetyFactor.Value;
+ if (calculationResult.RequiredSafetyFactor != null)
+ {
+ designRequiredFactor = calculationResult.RequiredSafetyFactor.Value;
+ }
+ }
+ }
+ }
+ }
+ if (res == double.MaxValue) res = DamGlobalConstants.NoRunValue;
+ return res;
+ }
+
+ ///
+ /// Get highest porbability of failure of all scenarios
+ ///
+ ///
+ private double GetHighestRealPropbabilityFromScenarios()
+ {
+ var res = double.MinValue;
+ List scenarios = Location.Scenarios;
+ foreach (var scenario in scenarios)
+ {
+ foreach (var calculationResult in scenario.CalculationResults)
+ {
+ if (calculationResult.Calculation.Equals("FlowSlide"))
+ {
+ designRequiredFactor = 1.0; // This is a hack to make FlowSlide color display correct;
+ // TODO: make a good generic method to display colored results
+ }
+ else
+ {
+ if (calculationResult.PipingFailureProbability != null)
+ {
+ if (calculationResult.PipingFailureProbability.Value > res &&
+ calculationResult.PipingFailureProbability.Value < DamGlobalConstants.NoRunValue)
+ {
+ res = calculationResult.PipingFailureProbability.Value;
+ if (calculationResult.RequiredFailureProbability != null)
+ {
+ designRequiredFactor = calculationResult.RequiredFailureProbability.Value;
+ }
+ }
+ }
+
+ }
+ }
+ }
+ if (res == double.MinValue) res = DamGlobalConstants.NoRunValue;
+ return res;
+ }
+
+ [Data]
+ [Label("Safety factor")]
+ [XmlIgnore]
+ [Format("F3")]
+ public double SafetyFactor
+ {
+ get
+ {
+ if (DamProjectType == DamProjectType.Calamity)
+ {
+ if (this.HasLocationResults)
+ {
+ TimeSerie timeSerie = this.LocationResult.StabilityTimeSerie;
+ return timeSerie.GetValue(CurrentTime);
+ }
+ else
+ {
+ return DamGlobalConstants.NoRunValue;
+ }
+ }
+ else if (DamProjectType == DamProjectType.Assessment)
+ {
+ if (this.HasRWScenarioResults && GetRWScenarioResultWithLowestSafetyFactor(currentScenarioType) != null)
+ {
+ return GetRWScenarioResultWithLowestSafetyFactor(currentScenarioType).SafetyFactor;
+ }
+ else
+ {
+ if (this.locationResult.RWScenariosResult != null &&
+ this.locationResult.RWScenariosResult.CalculationResult == CalculationResult.RunFailed)
+ {
+ // DamGlobalConstants.NoRunValue is the default result resulting in NoRun whereas the
+ // status must be failed. So when failed set to -1.
+ return -1;
+ }
+ else
+ {
+ return DamGlobalConstants.NoRunValue;
+ }
+ }
+ }
+ else if (DamProjectType == DamProjectType.Design)
+ {
+ return GetLowestRealSafetyFactorFromScenarios();
+ }
+ else
+ {
+ return DamGlobalConstants.NoRunValue;
+ }
+ }
+ }
+
+ [Data]
+ [Label("Detriment factor")]
+ [Format("F3")]
+ public double DetrimentFactor
+ {
+ get
+ {
+ if (DamProjectType == DamProjectType.Design)
+ {
+ return designRequiredFactor;
+ }
+ else
+ {
+ // For Piping in Assesment projects, ignore the given detriment factor and use the required safety for Piping
+ if (DamProjectType == DamProjectType.Assessment && (currentScenarioType == ScenarioType.Scenario10 || currentScenarioType == ScenarioType.Scenario11))
+ {
+ return DamGlobalConstants.RequiredSafetyPipingForAssessment;
+ }
+ return this.Location.DetrimentFactor;
+ }
+ }
+ }
+
+ [Data]
+ [Label("Failure probability")]
+ [XmlIgnore]
+ [Format("F3")]
+ public double FailureProbability
+ {
+ get
+ {
+ if (DamProjectType == DamProjectType.Calamity)
+ {
+ return DamGlobalConstants.NoRunValue;
+ }
+ else if (DamProjectType == DamProjectType.Assessment)
+ {
+ return DamGlobalConstants.NoRunValue;
+ }
+ else if (DamProjectType == DamProjectType.Design)
+ {
+ return GetHighestRealPropbabilityFromScenarios();
+ }
+ else
+ {
+ return DamGlobalConstants.NoRunValue;
+ }
+ }
+ }
+
+ [Data]
+ [Label("Required probability")]
+ [Format("F3")]
+ [XmlIgnore]
+ public double RequiredProbability
+ {
+ get
+ {
+ if (DamProjectType == DamProjectType.Design)
+ {
+ return designRequiredFactor; // only for piping at the moment
+ }
+ else
+ {
+ return 1; //#Bka: for now return 1 if not piping probabilistic.
+ }
+ }
+ }
+
+ public bool AreRWScenarioResultsMixed(ScenarioType scenarioType)
+ {
+ if (this.HasRWScenarioResults)
+ {
+ RWScenarioResult scenarioResult = this.LocationResult.RWScenariosResult.GetScenarioResult(scenarioType);
+ if (scenarioResult != null && scenarioResult.RWScenarioProfileResults.Count > 0)
+ {
+ var aboveRequiredSafety = false;
+ var belowRequiredSafety = false;
+ for (int i = 0; i < scenarioResult.RWScenarioProfileResults.Count; i++)
+ {
+ if (!aboveRequiredSafety)
+ {
+ aboveRequiredSafety = scenarioResult.RWScenarioProfileResults[i].SafetyFactor >= DetrimentFactor;
+ }
+ if (!belowRequiredSafety)
+ {
+ belowRequiredSafety = scenarioResult.RWScenarioProfileResults[i].SafetyFactor < DetrimentFactor;
+ }
+ }
+ return aboveRequiredSafety && belowRequiredSafety;
+ }
+ }
+ return false;
+ }
+
+ [Data]
+ [XmlIgnore]
+ [Label("Result")]
+ public JobResult Result
+ {
+ get
+ {
+ if (ProbabilisticType == ProbabilisticType.Deterministic)
+ {
+ if (DamProjectType == DamProjectType.Assessment && AreRWScenarioResultsMixed(currentScenarioType))
+ {
+ return JobResult.Mixed;
+ }
+ return JobResultInterpreter.GetJobResult(SafetyFactor, DetrimentFactor, true);
+ }
+ else
+ {
+ return JobResultInterpreter.GetJobResult(FailureProbability, RequiredProbability, false);
+ }
+ }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ public double X
+ {
+ get { return this.Location.XRd; }
+ set { this.Location.XRd = value; }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ public double Y
+ {
+ get { return this.Location.YRd; }
+ set { this.Location.YRd = value; }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ public static ScenarioType CurrentScenarioType
+ {
+ get { return currentScenarioType; }
+ set { currentScenarioType = value; }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ public static string CurrentProfileName
+ {
+ get { return currentProfileName; }
+ set { currentProfileName = value; }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ public static string CurrentScenarioName
+ {
+ get { return currentScenarioName; }
+ set { currentScenarioName = value; }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ public static string CurrentCalculation
+ {
+ get { return currentCalculation; }
+ set { currentCalculation = value; }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ public static DateTime CurrentTime
+ {
+ get { return currentTime; }
+ set { currentTime = value; }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ public static DamProjectType DamProjectType
+ {
+ get { return damProjectType; }
+ set { damProjectType = value; }
+ }
+
+ [XmlIgnore]
+ [Browsable(false)]
+ public static ProbabilisticType ProbabilisticType
+ {
+ get { return probabilisticType; }
+ set { probabilisticType = value; }
+ }
+
+ public bool IsEnabled(string property)
+ {
+ return true;
+ }
+
+ public bool IsVisible(string property)
+ {
+ switch (property)
+ {
+ case "SafetyFactor": return this.Result != JobResult.NoRun && this.Result != JobResult.Failed &&
+ ProbabilisticType == ProbabilisticType.Deterministic;
+ case "DetrimentFactor": return this.Result != JobResult.NoRun && this.Result != JobResult.Failed &&
+ ProbabilisticType == ProbabilisticType.Deterministic;
+ case "RequiredProbability": return this.Result != JobResult.NoRun && this.Result != JobResult.Failed &&
+ ProbabilisticType != ProbabilisticType.Deterministic;
+ case "FailureProbability": return this.Result != JobResult.NoRun && this.Result != JobResult.Failed &&
+ ProbabilisticType != ProbabilisticType.Deterministic;
+ case "WaterLevelTimeSerie":
+ return HasLocationResults;
+ case "RWScenarioResults":
+ return HasRWScenarioResults;
+ default: return true;
+ }
+ }
+
+ public override string ToString()
+ {
+ return this.Location != null ? this.Location.ToString() : "";
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryPoint.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryPoint.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryPoint.cs (revision 274)
@@ -0,0 +1,184 @@
+// 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 publisherEventArgs GeometryPoint
+ ///
+ public virtual double X { get; set; }
+
+ ///
+ /// Gets or sets the Z coordinate of publisherEventArgs 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/branches/Initial Source/Deltares.DamEngine.Data/Standard/Logging/LogMessage.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Logging/LogMessage.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Logging/LogMessage.cs (revision 274)
@@ -0,0 +1,110 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard.Logging
+{
+ ///
+ /// Class for logmessages
+ ///
+ public class LogMessage
+ {
+ private string message = "";
+ private LogMessageType messageType = LogMessageType.Info;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public LogMessage() {}
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Type of the message.
+ /// The subject.
+ /// The message.
+ public LogMessage(LogMessageType messageType, object subject, string message)
+ {
+ this.messageType = messageType;
+ Subject = subject;
+ this.message = message;
+ }
+
+ ///
+ /// Gets or sets the type of the message.
+ ///
+ ///
+ /// The type of the message.
+ ///
+ [XmlAttribute]
+ public LogMessageType MessageType
+ {
+ get
+ {
+ return messageType;
+ }
+ set
+ {
+ messageType = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the subject.
+ ///
+ ///
+ /// The subject.
+ ///
+ [XmlIgnore]
+ public object Subject { get; set; }
+
+ ///
+ /// Gets or sets the message.
+ ///
+ ///
+ /// The message.
+ ///
+ [XmlAttribute]
+ public string Message
+ {
+ get
+ {
+ return message;
+ }
+ set
+ {
+ message = value;
+ }
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return Message;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Validation/IValidationResult.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Validation/IValidationResult.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Validation/IValidationResult.cs (revision 274)
@@ -0,0 +1,78 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard.Validation
+{
+ // all these setters are to make sure BindSupport doesn't gray out the fields...
+ // but they shouldn't really be here
+ ///
+ /// Interface IValidationResult
+ ///
+ public interface IValidationResult
+ {
+ ///
+ /// Gets the type of the message.
+ ///
+ ///
+ /// The type of the message.
+ ///
+ ValidationResultType MessageType { get; }
+
+ ///
+ /// Gets the invalid properties.
+ ///
+ ///
+ /// The invalid properties.
+ ///
+ List InvalidProperties { get; }
+
+ ///
+ /// Gets or sets the text.
+ ///
+ ///
+ /// The text.
+ ///
+ string Text { get; set; }
+
+ ///
+ /// Gets or sets the subject.
+ ///
+ ///
+ /// The subject.
+ ///
+ object Subject { get; set; }
+
+ ///
+ /// Gets the identifier.
+ ///
+ ///
+ /// The identifier.
+ ///
+ List ID { get; }
+
+ ///
+ /// Clears the validation result.
+ ///
+ void ClearValidationResult();
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWEvaluator.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWEvaluator.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWEvaluator.cs (revision 274)
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2011 Deltares. All rights reserved.
+//
+// Rob Brinkman
+// rob.brinkman@deltares.nl
+// 23-06-2011
+// base class for evaluators
+//-----------------------------------------------------------------------
+
+using System;
+using Deltares.Dam.Data;
+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/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryBounds.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryBounds.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryBounds.cs (revision 274)
@@ -0,0 +1,119 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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/branches/Initial Source/Deltares.DamEngine.Data/General/CompositeJob.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/CompositeJob.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/CompositeJob.cs (revision 274)
@@ -0,0 +1,70 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class CompositeJob : DamJob
+ {
+ private IList jobs = new List();
+
+ public CompositeJob()
+ {
+ }
+
+ public CompositeJob(object subject) : base(subject)
+ {
+ }
+
+ public override bool? Run
+ {
+ get
+ {
+ bool containsRun = false;
+ bool containsNoRun = false;
+
+ foreach (DamJob job in jobs)
+ {
+ if (!job.Run.HasValue)
+ {
+ containsRun = true;
+ containsNoRun = true;
+ }
+ else if (job.Run.Value)
+ {
+ containsRun = true;
+ }
+ else
+ {
+ containsNoRun = true;
+ }
+ }
+
+ if (containsRun && containsNoRun)
+ {
+ return null;
+ }
+ else if (containsRun)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ set
+ {
+ foreach (DamJob job in jobs)
+ {
+ job.Run = value;
+ }
+ }
+ }
+
+ public virtual IList Jobs
+ {
+ get { return jobs; }
+ set { jobs = value; }
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Soil.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Soil.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Soil.cs (revision 274)
@@ -0,0 +1,385 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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;
+using Deltares.DamEngine.Data.Standard.Language;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Soil class, representing a specific soil material and its properties
+ ///
+ [Serializable]
+ public class Soil : IName
+ {
+ // Stability properties
+ private string name = "";
+ private DilatancyType dilatancyType = DilatancyType.Phi;
+ private ShearStrengthModel shearStrengthModel = ShearStrengthModel.CPhi;
+ private double belowPhreaticLevel = double.NaN;
+ private double abovePhreaticLevel = double.NaN;
+ private double cohesion = double.NaN;
+ private double frictionAngle = double.NaN;
+ private double poP = double.NaN;
+ private double ocr = double.NaN;
+ private double ratioCuPc = double.NaN;
+ private double cuTop = double.NaN;
+ private double cuBottom = double.NaN;
+ private bool usePop = true;
+ private double strengthIncreaseExponent = double.NaN;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Soil()
+ {
+ Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSoilMaterial");
+ }
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The name.
+ /// Unit weight below phreatic level
+ /// Unit weight above phreatic level
+ public Soil(string name, double belowPhreaticLevel, double abovePhreaticLevel) : this()
+ {
+ Name = name;
+ AbovePhreaticLevel = abovePhreaticLevel;
+ BelowPhreaticLevel = belowPhreaticLevel;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The name.
+ public Soil(string name) : this()
+ {
+ Name = name;
+ }
+
+ #region property Name
+
+ ///
+ /// Gets or sets the name of the soil.
+ ///
+ public string Name
+ {
+ get
+ {
+ return name;
+ }
+ set
+ {
+ name = value;
+ }
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ #endregion property Name
+
+
+ #region property BelowPhreaticLevel
+
+ ///
+ /// Unit Weight below the phreatic level (kN/m3)
+ ///
+ public double BelowPhreaticLevel
+ {
+ set
+ {
+ belowPhreaticLevel = value;
+ }
+ get
+ {
+ return belowPhreaticLevel;
+ }
+ }
+ #endregion
+
+ #region property AbovePhreaticLevel
+
+ ///
+ /// Unit Weight above the phreatic level (kN/m3)
+ ///
+ public double AbovePhreaticLevel
+ {
+ set
+ {
+ abovePhreaticLevel = value;
+ }
+ get
+ {
+ return abovePhreaticLevel;
+ }
+ }
+
+ #endregion
+
+ #region property Cohesion
+
+ ///
+ /// Cohesion (the force that holds together molecules or like particles within a soil) [kN/m2]
+ ///
+ public double Cohesion
+ {
+ get
+ {
+ return cohesion;
+ }
+ set
+ {
+ cohesion = value;
+ }
+ }
+
+ #endregion
+
+ #region property FrictionAngle
+
+ ///
+ /// Critical state friction angle (deg)
+ ///
+ public double FrictionAngle //gedaan
+ {
+ get
+ {
+ return frictionAngle;
+ }
+ set
+ {
+ frictionAngle = value;
+ }
+ }
+ #endregion property FrictionAngle
+
+
+
+ #region property POP
+
+ ///
+ /// Pre-overburden pressure (POP)
+ /// Equal to pre-consolidation stress minus effective stress
+ ///
+ public double PoP
+ {
+ get
+ {
+ return poP;
+ }
+ set
+ {
+ poP = value;
+ }
+ }
+ #endregion property POP
+
+ #region property OCR
+
+ ///
+ /// Over-consolidation ratio (OCR)
+ ///
+ public double Ocr
+ {
+ get
+ {
+ return ocr;
+ }
+ set
+ {
+ ocr = value;
+ }
+ }
+ #endregion property OCR
+
+ #region property RatioCuPc
+
+ ///
+ /// Ratio Cu/Pc
+ ///
+ public double RatioCuPc
+ {
+ get
+ {
+ return ratioCuPc;
+ }
+ set
+ {
+ ratioCuPc = value;
+ }
+ }
+ #endregion property RatioCuPc
+
+
+
+ #region property CuTop
+
+ ///
+ /// Cu Top
+ ///
+ public double CuTop
+ {
+ get
+ {
+ return cuTop;
+ }
+ set
+ {
+ cuTop = value;
+ }
+ }
+ #endregion property CuTop
+
+ #region property CuBottom
+
+ ///
+ /// Cu Bottom
+ ///
+ public double CuBottom
+ {
+ get
+ {
+ return cuBottom;
+ }
+ set
+ {
+ cuBottom = value;
+ }
+ }
+ #endregion property CuBottom
+
+ #region property UsePop
+
+ ///
+ /// Use POP for shear strength model
+ ///
+ public bool UsePop
+ {
+ get
+ {
+ return usePop;
+ }
+ set
+ {
+ usePop = value;
+ }
+ }
+ #endregion property UsePop
+
+ #region property DilatancyType
+
+ ///
+ /// Dilatancy (shear thickening) type
+ ///
+ public DilatancyType DilatancyType
+ {
+ get
+ {
+ return dilatancyType;
+ }
+ set
+ {
+ if (!dilatancyType.Equals(value))
+ {
+ dilatancyType = value;
+ }
+ }
+ }
+
+ #endregion property DilatancyType
+
+ #region property StrengthIncreaseExponent
+
+ ///
+ /// Gets or sets the strength increase exponent.
+ ///
+ ///
+ /// The strength increase exponent.
+ ///
+ public double StrengthIncreaseExponent
+ {
+ get
+ {
+ return strengthIncreaseExponent;
+ }
+ set
+ {
+ strengthIncreaseExponent = value;
+ }
+ }
+ #endregion property StrengthIncreaseExponent
+
+ #region property ShearStrengthModel
+
+ ///
+ /// Shear strength model to use
+ ///
+ [XmlAttribute("ShearStrengthModel")]
+ public ShearStrengthModel ShearStrengthModel
+ {
+ get
+ {
+ return shearStrengthModel;
+ }
+ set
+ {
+ shearStrengthModel = value;
+ }
+ }
+ #endregion property ShearStrengthModel
+
+
+ ///
+ /// Assigns the specified a soil.
+ ///
+ /// a soil.
+ public void Assign(Soil aSoil)
+ {
+ name = aSoil.Name;
+ dilatancyType = aSoil.DilatancyType;
+ shearStrengthModel = aSoil.ShearStrengthModel;
+ belowPhreaticLevel = aSoil.BelowPhreaticLevel;
+ abovePhreaticLevel = aSoil.AbovePhreaticLevel;
+ cohesion = aSoil.Cohesion;
+ frictionAngle = aSoil.FrictionAngle;
+ poP = aSoil.PoP;
+ ocr = aSoil.Ocr;
+ ratioCuPc = aSoil.RatioCuPc;
+ cuTop = aSoil.CuTop;
+ cuBottom = aSoil.CuBottom;
+ usePop = aSoil.UsePop;
+ strengthIncreaseExponent = aSoil.StrengthIncreaseExponent;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenarioSelector.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenarioSelector.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenarioSelector.cs (revision 274)
@@ -0,0 +1,228 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Data.General;
+
+namespace Deltares.DamEngine.Data.RWScenarios
+{
+ public class RWScenarioSelector
+ {
+ public RWScenarioSelector()
+ {
+ }
+
+ public PipingModelType PipingModelType { get; set; }
+ public MStabParameters MStabParameters { get; set; }
+
+ private bool WillChoicesResultInScenarios(params Enum[] previousChoices)
+ {
+ if (previousChoices.Length >= 2)
+ {
+ if (previousChoices[0].Equals(LoadSituation.Dry) && previousChoices[1].Equals(DikeDrySensitivity.None))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public RWScenarioProfileResult[] GetScenarios(Location location, SoilGeometryProbability soilGeometryProbability)
+ {
+ List scenarios = new List();
+
+ RWEvaluator[] evaluators = new RWEvaluator[]
+ {
+ new DikeMaterialRWEvaluator(),
+ new HydraulicShortcutRWEvaluator(),
+ new UpliftRWEvaluator()
+ };
+
+ Enum[] choices = new Enum[evaluators.Length + 1];
+ foreach (LoadSituation loadSituation in Enum.GetValues(typeof(LoadSituation)))
+ {
+ choices[0] = loadSituation;
+
+ bool resultsInScenarios = true;
+
+ for (int i = 1; i < evaluators.Length + 1; i++)
+ {
+ choices[i] = evaluators[i - 1].Evaluate(location, new SoilGeometry(soilGeometryProbability.SoilProfile, null), choices.ToArray());
+
+ //Is het een doorlopende tak? Zo niet break af (afbreken als geen veenkade en droge belastingsituatie
+ resultsInScenarios = WillChoicesResultInScenarios(choices.ToArray());
+
+ if (!resultsInScenarios)
+ {
+ break;
+ }
+ }
+
+ if (resultsInScenarios)
+ {
+ if (choices[0].Equals(LoadSituation.Wet))
+ {
+ if (choices[1].Equals(DikeDrySensitivity.None))
+ {
+ if (choices[2].Equals(HydraulicShortcutType.NoHydraulicShortcut))
+ {
+ if (choices[3].Equals(UpliftType.NoUplift))
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario08, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ }
+ else // UpliftType.Uplift
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario04, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.UpliftVan));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario08, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario10, choices, location, soilGeometryProbability, FailureMechanismSystemType.Piping, PipingModelType));
+ }
+ }
+ else // HydraulicShortcutType.HydraulicShortcut
+ {
+ if (choices[3].Equals(UpliftType.NoUplift))
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario07, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ }
+ else // UpliftType.Uplift
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario03, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.UpliftVan));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario07, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario10, choices, location, soilGeometryProbability, FailureMechanismSystemType.Piping, PipingModelType));
+ }
+ }
+ }
+ else // DikeDrySensitivity.Dry
+ {
+ if (choices[2].Equals(HydraulicShortcutType.NoHydraulicShortcut))
+ {
+ if (choices[3].Equals(UpliftType.NoUplift))
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario08, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ }
+ else // UpliftType.Uplift
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario04, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.UpliftVan));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario08, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario10, choices, location, soilGeometryProbability, FailureMechanismSystemType.Piping, PipingModelType));
+ }
+ }
+ else // HydraulicShortcutType.HydraulicShortcut
+ {
+ if (choices[3].Equals(UpliftType.NoUplift))
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario07, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ }
+ else // UpliftType.Uplift
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario03, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.UpliftVan));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario07, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario10, choices, location, soilGeometryProbability, FailureMechanismSystemType.Piping, PipingModelType));
+ }
+ }
+ }
+ }
+ else // LoadSituation.Dry
+ {
+ if (choices[1].Equals(DikeDrySensitivity.Dry))
+ {
+ if (choices[2].Equals(HydraulicShortcutType.NoHydraulicShortcut))
+ {
+ if (choices[3].Equals(UpliftType.NoUplift))
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario06, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ }
+ else // UpliftType.Uplift
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario02, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.UpliftVan));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario06, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario09, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.HorizontalBalance));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario11, choices, location, soilGeometryProbability, FailureMechanismSystemType.Piping, PipingModelType));
+ }
+ }
+ else // HydraulicShortcutType.HydraulicShortcut
+ {
+ if (choices[3].Equals(UpliftType.NoUplift))
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario05, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ }
+ else // UpliftType.Uplift
+ {
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario01, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.UpliftVan));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario05, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.Bishop));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario09, choices, location, soilGeometryProbability, FailureMechanismSystemType.StabilityInside, MStabModelType.HorizontalBalance));
+ scenarios.Add(this.GetScenario(ScenarioType.Scenario11, choices, location, soilGeometryProbability, FailureMechanismSystemType.Piping, PipingModelType));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return scenarios.ToArray();
+ }
+
+ private RWScenarioProfileResult GetScenario(ScenarioType scenarioType, Enum[] choices, Location location,
+ SoilGeometryProbability soilGeometryProbability, FailureMechanismSystemType failureMechanismType, MStabModelType modelOption)
+ {
+ RWScenarioProfileResult scenario = new RWScenarioProfileResult();
+ scenario.Location = location;
+ scenario.SoilGeometryProbability = soilGeometryProbability;
+ scenario.FailureMechanismType = failureMechanismType;
+ scenario.MstabModelOption = modelOption;
+ scenario.PipingModelOption = PipingModelType;
+ scenario.MStabParameters = MStabParameters;
+ scenario.LoadSituation = (LoadSituation)choices[0];
+ scenario.DikeDrySensitivity = (DikeDrySensitivity)choices[1];
+ scenario.HydraulicShortcutType = (HydraulicShortcutType)choices[2];
+ scenario.UpliftType = (UpliftType)choices[3];
+
+ scenario.ScenarioType = scenarioType;
+
+ //if (scenario.IsDry)
+ //{
+ // // Soils are not transferred to the computational core at the moment, therefore this code has no meaning at the moment
+ // // You could say the same about soils in general in the DAM C# code
+ // SoilProfile drySoilProfile = soilProfile.Clone();
+ // foreach (Layer layer in drySoilProfile.Layers)
+ // {
+ // layer.Soil.AbovePhreaticLevel = layer.Soil.DryUnitWeight;
+ // }
+ //}
+
+ return scenario;
+ }
+
+ private RWScenarioProfileResult GetScenario(ScenarioType scenarioType, Enum[] choices, Location location,
+ SoilGeometryProbability soilGeometryProbability, FailureMechanismSystemType failureMechanismType, PipingModelType pipingModelType)
+ {
+ RWScenarioProfileResult scenario = new RWScenarioProfileResult();
+ scenario.Location = location;
+ scenario.SoilGeometryProbability = soilGeometryProbability;
+ scenario.FailureMechanismType = failureMechanismType;
+ scenario.MstabModelOption = MStabModelType.Bishop;
+ scenario.PipingModelOption = pipingModelType;
+
+ scenario.LoadSituation = (LoadSituation)choices[0];
+ scenario.DikeDrySensitivity = (DikeDrySensitivity)choices[1];
+ scenario.HydraulicShortcutType = (HydraulicShortcutType)choices[2];
+ scenario.UpliftType = (UpliftType)choices[3];
+
+ scenario.ScenarioType = scenarioType;
+
+ //if (scenario.IsDry)
+ //{
+ // // Soils are not transferred to the computational core at the moment, therefore this code has no meaning at the moment
+ // // You could say the same about soils in general in the DAM C# code
+ // SoilProfile drySoilProfile = soilProfile.Clone();
+ // foreach (Layer layer in drySoilProfile.Layers)
+ // {
+ // layer.Soil.AbovePhreaticLevel = layer.Soil.DryUnitWeight;
+ // }
+ //}
+
+ return scenario;
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamGlobalConstants.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamGlobalConstants.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamGlobalConstants.cs (revision 274)
@@ -0,0 +1,10 @@
+namespace Deltares.DamEngine.Data.General
+{
+ public static class DamGlobalConstants
+ {
+ public const double NoRunValue = 99;
+ public const double RequiredSafetyPipingForAssessment = 1.2;
+ public const double PlLineOffsetFactorBelowShoulderCrestMinValue = 0.0;
+ public const double PlLineOffsetFactorBelowShoulderCrestMaxValue = 1.0;
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/IName.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/IName.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/IName.cs (revision 274)
@@ -0,0 +1,39 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard
+{
+ ///
+ /// Use this interface for (auto) naming purpose in combination with
+ /// UniqueNameProvider.ProvideUniqueName
+ ///
+ ///
+ ///
+ /// UniqueNameProvider
+ ///
+ public interface IName
+ {
+ ///
+ /// The unique name of the object.
+ ///
+ string Name { get; set; }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Dike.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Dike.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Dike.cs (revision 274)
@@ -0,0 +1,461 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2009 Deltares. All rights reserved.
+//
+// R.C. blankenburgh
+// remko.blankenburgh@deltares.nl
+// 26-08-2009
+// n.a.
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.Design;
+using Deltares.DamEngine.Data.General.PlLines;
+using Deltares.DamEngine.Data.Geotechnics;
+using Deltares.DamEngine.Data.Standard;
+using Deltares.DamEngine.Data.Standard.Language;
+using Deltares.DamEngine.Data.Standard.Logging;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class DikeException : Exception
+ {
+ public DikeException(string message)
+ : base(message)
+ {
+ }
+ }
+
+ public class DikeParameterNames
+ {
+ public const string MapForSoilGeometries2D = "MapForSoilGeometries2D";
+ }
+
+ public class Dike: IDisposable
+ {
+ private string description = "";
+ public virtual string MapForSoilGeometries2D { get; set; }
+ private IList locations;
+
+ private IList pl1Lines;
+ private bool removeStiFiles;
+ private MStabShearStrength shearmodel;
+ private SoilList soilList;
+ private IList gauges = new List();
+ private IList gaugePLLines = new List();
+ private IList nonWaterRetainingObjects;
+ private IList soilProfiles;
+ private string soilDatabaseName = "";
+ private List databaseSoils = new List();
+
+ public Dike()
+ {
+ this.Name = "Dijkring";
+ this.MapForSoilGeometries2D = "";
+
+ this.locations = new List();
+ this.soilProfiles = new List();
+
+ this.surfaceLines = new DelegatedList { AddMethod = ConvertAddedOldSurfaceLineToNewFormat };
+ SurfaceLines2 = new List();
+ this.pl1Lines = new List();
+ this.soilList = new SoilList();
+ this.nonWaterRetainingObjects = new List();
+ removeStiFiles = true;
+ }
+
+ public bool IsRemoveStiFiles { get { return removeStiFiles; } set { removeStiFiles = value; } }
+ public MStabShearStrength ShearStrengthModel { get { return shearmodel; } set { shearmodel = value; } }
+
+ public virtual string Name { get; set; }
+
+ public virtual string SoilDatabaseName
+ {
+ get { return this.soilDatabaseName; }
+ set
+ {
+ this.soilDatabaseName = value;
+ UpdateLocationsDatabaseName();
+ }
+ }
+
+ ///
+ /// Updates the locations for scenarios.
+ ///
+ public void UpdateLocationsForScenarios()
+ {
+ foreach (Location location in this.Locations)
+ {
+ foreach (Scenario scenario in location.Scenarios)
+ {
+ scenario.Location = location;
+ }
+ }
+ }
+
+ ///
+ /// Updates the name soil database for all locations.
+ ///
+ public void UpdateLocationsDatabaseName()
+ {
+ foreach (Location location in this.Locations)
+ {
+ location.SoildatabaseName = this.SoilDatabaseName;
+ }
+
+ }
+
+ [XmlIgnore]
+ public SoilbaseDB SoilBaseDB { get; set; }
+
+ ///
+ /// Gets the locations.
+ ///
+ ///
+ /// The locations.
+ ///
+ public virtual IList Locations
+ {
+ get { return this.locations; }
+ private set { this.locations = value; }
+ }
+
+ ///
+ /// Sorts the locations.
+ ///
+ public void SortLocations()
+ {
+ this.locations = this.Locations.OrderBy(o => o.Name).ToList();
+ }
+
+ public IList SurfaceLines2 { get; set; }
+
+ public virtual IList PL1Lines
+ {
+ get { return this.pl1Lines; }
+ set { this.pl1Lines = value; }
+ }
+
+ public virtual IList SoilProfiles
+ {
+ get { return this.soilProfiles; }
+ set { this.soilProfiles = value; }
+ }
+
+ public virtual SoilList SoilList
+ {
+ get { return this.soilList; }
+ set { this.soilList = value; }
+ }
+
+ [Browsable(false)]
+ public virtual IList Gauges
+ {
+ get { return this.gauges; }
+ set { this.gauges = value; }
+ }
+
+ [Browsable(false)]
+ public virtual IList GaugePLLines
+ {
+ get { return this.gaugePLLines; }
+ set { this.gaugePLLines = value; }
+ }
+
+ public virtual IList NonWaterRetainingObjects
+ {
+ get { return this.nonWaterRetainingObjects; }
+ set { this.nonWaterRetainingObjects = value; }
+ }
+
+ public bool UsesGauges { get { return this.GaugePLLines != null && this.GaugePLLines.Count > 0 && this.Gauges != null; } }
+
+ public virtual List Scenarios
+ {
+ get
+ {
+ var scenarios = new List();
+ foreach (Location location in Locations)
+ {
+ scenarios.AddRange(location.Scenarios);
+ }
+ return scenarios;
+ }
+ }
+
+ public string Description
+ {
+ get { return description; }
+ set { description = value; }
+ }
+
+ public void Validate()
+ {
+ if (Locations == null || Locations.Count < 1)
+ {
+ throw new DikeException("The dike ring has no locations defined");
+ }
+ foreach (Location location in Locations)
+ {
+ if (location.LocalXZSurfaceLine2 != null)
+ {
+ var validator = new SurfaceLine2Validator();
+ var validationResults = validator.ValidateCharacteristicPointsAreOrdered(location.LocalXZSurfaceLine2)
+ .Concat(validator.ValidateGeometryPointsAreOrdered(location.LocalXZSurfaceLine2)).ToArray();
+ if (validationResults.Length > 0)
+ {
+ throw new SurfaceLineException(validationResults[0].Text);
+ }
+ }
+ }
+ }
+
+ public void CreateSoilBase()
+ {
+ if (this.SoilDatabaseName == null || !File.Exists(this.SoilDatabaseName))
+ {
+ throw new DikeException(String.Format("The soil database '{0}' cannot be found", this.SoilDatabaseName));
+ }
+ this.SoilBaseDB = SoilbaseDB.Create(this.SoilDatabaseName);
+ }
+
+ ///
+ /// Read all the soils and their parameters from the database
+ ///
+ public void FillDataBaseSoilListFromSoilBase()
+ {
+ using (var geoDatabase = new GeoDatabase(this.SoilDatabaseName))
+ {
+ geoDatabase.ReUseSoils = true;
+ var newSoilList = geoDatabase.ReadSoils(soilList.Soils);
+ databaseSoils = newSoilList.Soils;
+ }
+ }
+
+ ///
+ /// Add 1D-soilprofiles from MGeobase database
+ ///
+ public void AddSoilProfilesFromDB()
+ {
+ if (this.SoilDatabaseName == null || !File.Exists(this.SoilDatabaseName))
+ {
+ throw new DikeException(String.Format("The MGeobase database '{0}' cannot be found", this.SoilDatabaseName));
+ }
+ if (soilList.Soils.Count == 0)
+ {
+ FillDataBaseSoilListFromSoilBase();
+ soilList.Soils.AddRange(databaseSoils);
+ }
+ if (soilList.Soils.Count == 0)
+ {
+ throw new DikeException(String.Format("The MGeobase database '{0}' does not contain soils and can not be used.", this.SoilDatabaseName));
+ }
+ MGeobaseDB mgbDB = new MGeobaseDB(soilList);
+ IList addedSoilProfiles = mgbDB.AddSoilProfiles(this.SoilDatabaseName);
+ foreach (var addedSoilProfile in addedSoilProfiles)
+ {
+ soilProfiles.Add(addedSoilProfile);
+ }
+ }
+
+ ///
+ /// Adapt data so it is consistent
+ ///
+ public List MakeDataConsistent()
+ {
+ var errorSoils = TryToMakeSoilDataConsistent();
+ var logMessages = new List();
+ // Delete all locations without surfaceline
+ logMessages.AddRange(DeleteLocationsWithoutSurfaceLines());
+ // Delete all locations that have profiles (in their segment) which hold soils
+ // that are not in the soil database and so have no parameters.
+ logMessages.AddRange(DeleteLocationsWithProfilesWithUnknownSoils(errorSoils));
+ return logMessages;
+ }
+
+ ///
+ /// Tries to make the soil data as read for 1D profiles consistent with the data in the soil database.
+ /// In the end we have a neat soil list with parameters for every soil as read from the database.
+ /// We might have a list with errors (soils that were not to be found in the database so soils for which
+ /// no parameters could be found).
+ ///
+ ///
+ private List TryToMakeSoilDataConsistent()
+ {
+ var errorSoils = new List();
+ // Fill the list of errorSoils with soils that are in the current soillist (as result of importing
+ // 1D profiles) but that are not found in the soil database because that are errors
+ foreach (var soil in soilList.Soils)
+ {
+ var fs = databaseSoils.Find(t => String.Equals(t.Name, soil.Name, StringComparison.CurrentCultureIgnoreCase));
+ if (fs == null)
+ {
+ errorSoils.Add(soil);
+ }
+ }
+ // Remove the error soils form the list
+ foreach (var errorSoil in errorSoils)
+ {
+ soilList.Soils.Remove(errorSoil);
+ }
+ // Get the parameters for every soil in the now proper soil list from the database. Add soils
+ // that are in the database but not yet in the soil list.
+ foreach (Soil soil in databaseSoils)
+ {
+ Soil existingSoil = this.soilList.GetSoilByName(soil.Name);
+ if (existingSoil == null)
+ {
+ this.soilList.Soils.Add(soil);
+ }
+ else
+ {
+ existingSoil.Assign(soil);
+ }
+ }
+ return errorSoils;
+ }
+
+ ///
+ /// Removes all locations which have profiles that have invalid soils
+ ///
+ private List DeleteLocationsWithProfilesWithUnknownSoils(List invalidSoils)
+ {
+ var logMessages = new List();
+ var invalidLocations = new List();
+ string soilProf;
+ string invSoil;
+ foreach (var location in locations)
+ {
+ bool isInValid;
+ string message = "";
+ if (location.Segment == null)
+ {
+ isInValid = true;
+ message = String.Format(LocalizationManager.GetTranslatedText(this.GetType(), "LocationWitNameHasNoSegment"), location.Name);
+ }
+ else
+ {
+ isInValid = DoesLocationHaveInvalidSoils(invalidSoils, location, out soilProf, out invSoil);
+ if (isInValid)
+ {
+ message = String.Format(LocalizationManager.GetTranslatedText(this.GetType(), "locationHasProfileWithInvalidSoils"), location.Name, soilProf, invSoil);
+ }
+ }
+ if (isInValid)
+ {
+ invalidLocations.Add(location);
+ logMessages.Add(new LogMessage(LogMessageType.Warning, this, message));
+ }
+ }
+ foreach (var invalidLocation in invalidLocations)
+ {
+
+ locations.Remove(invalidLocation);
+ }
+ return logMessages;
+ }
+
+ ///
+ /// Checks wether a location (or rather the soilprofiles in the segement of the location) contains invalid soils.
+ /// A soil is hereby considered invalid if it is not found in the database.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private bool DoesLocationHaveInvalidSoils(List invalidSoils, Location location, out string soilProf, out string invSoil)
+ {
+ soilProf = " ";
+ invSoil = " ";
+ foreach (var spp in location.Segment.SoilProfileProbabilities)
+ {
+ foreach (var invalidSoil in invalidSoils)
+ {
+ var fl = spp.SoilProfile.Layers.Find(l => String.Equals(l.Soil.Name, invalidSoil.Name, StringComparison.CurrentCultureIgnoreCase));
+
+ if (fl != null)
+ {
+ soilProf = spp.SoilProfile.Name;
+ invSoil = invalidSoil.Name;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Delete all locations without surfacelines
+ ///
+ private List DeleteLocationsWithoutSurfaceLines()
+ {
+ var logMessages = new List();
+
+ //Add all locations with valid surfaceline
+ var newLocations = new List();
+ newLocations.AddRange(this.Locations.Where(loc => loc.SurfaceLine2 != null));
+
+ // Report which locations are not added because no valid surfaceline is found
+ var deletedLocations = new List();
+ deletedLocations.AddRange(this.Locations.Where(loc => loc.SurfaceLine2 == null));
+ foreach (var deletedLocation in deletedLocations)
+ {
+ var locationHasNoSurfaceLine = LocalizationManager.GetTranslatedText(this.GetType(), "LocationHasNoSurfaceLine");
+ logMessages.Add(new LogMessage(LogMessageType.Warning, this,
+ String.Format(locationHasNoSurfaceLine, deletedLocation.Name)));
+ }
+
+ this.Locations = newLocations;
+ return logMessages;
+ }
+
+ public override string ToString()
+ {
+ return this.Name;
+ }
+
+ public Dictionary GetParametersAsNameValuePairs()
+ {
+ var nameValuePairs = new Dictionary();
+ nameValuePairs.Add(DikeParameterNames.MapForSoilGeometries2D, MapForSoilGeometries2D);
+ return nameValuePairs;
+ }
+
+ public void SetParameterFromNameValuePair(string parameterName, string parameterValue)
+ {
+ if (parameterName.Equals(DikeParameterNames.MapForSoilGeometries2D))
+ this.MapForSoilGeometries2D = parameterValue;
+ }
+
+ public void UpdateLocation(Location location)
+ {
+ location.SoildatabaseName = this.SoilDatabaseName;
+ location.SoilList = this.SoilList;
+ location.MapForSoilGeometries2D = this.MapForSoilGeometries2D;
+
+ location.Gauges.Clear();
+ location.Gauges.AddRange(this.Gauges);
+
+ location.GaugePLLines.Clear();
+ location.GaugePLLines.AddRange(this.GaugePLLines);
+ }
+
+ public void Dispose()
+ {
+ foreach (var location in Locations)
+ {
+ location.Dispose();
+ }
+ foreach (var surfaceLine2 in SurfaceLines2)
+ {
+ surfaceLine2.Dispose();
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer.cs (revision 274)
@@ -0,0 +1,74 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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/branches/Initial Source/Deltares.DamEngine.Data/Standard/Logging/LogMessageType.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Logging/LogMessageType.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Logging/LogMessageType.cs (revision 274)
@@ -0,0 +1,54 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard.Logging
+{
+ ///
+ /// Types for logmessages
+ ///
+ public enum LogMessageType
+ {
+ ///
+ /// The trace
+ ///
+ Trace,
+ ///
+ /// The debug
+ ///
+ Debug,
+ ///
+ /// The information
+ ///
+ Info,
+ ///
+ /// The warning
+ ///
+ Warning,
+ ///
+ /// The error
+ ///
+ Error,
+ ///
+ /// The fatal error
+ ///
+ FatalError
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/DikeMaterialRWEvaluator.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/DikeMaterialRWEvaluator.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/DikeMaterialRWEvaluator.cs (revision 274)
@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2011 Deltares. All rights reserved.
+//
+// Rob Brinkman
+// rob.brinkman@deltares.nl
+// 23-06-2011
+// Evaluate what type of dike material
+//-----------------------------------------------------------------------
+
+using System;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Data.General;
+
+namespace Deltares.DamEngine.Data.RWScenarios
+{
+ public class DikeMaterialRWEvaluator : RWEvaluator
+ {
+ public DikeMaterialRWEvaluator()
+ {
+ }
+
+ public override Enum Evaluate(Location location, SoilGeometry soilGeometry, params Enum[] previousChoices)
+ {
+ base.Evaluate(location, soilGeometry, previousChoices);
+
+ if (location.DikeMaterialType == SoilType.Peat)
+ {
+ return DikeDrySensitivity.Dry;
+ }
+ else
+ {
+ return DikeDrySensitivity.None;
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/LanguageType.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/LanguageType.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/LanguageType.cs (revision 274)
@@ -0,0 +1,38 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard.Language
+{
+ ///
+ /// enum LanguageType
+ ///
+ public enum LanguageType
+ {
+ ///
+ /// The english
+ ///
+ English,
+ ///
+ /// The dutch
+ ///
+ Dutch
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/LineHelper.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/LineHelper.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/LineHelper.cs (revision 274)
@@ -0,0 +1,109 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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
+ {
+ ///
+ /// 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);
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenariosResult.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenariosResult.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/RWScenariosResult.cs (revision 274)
@@ -0,0 +1,320 @@
+
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.RWScenarios;
+using Deltares.Standard.Attributes;
+
+namespace Deltares.Dam.Data
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.Drawing;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+ using Deltares.Soilbase;
+
+ 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()
+ {
+ }
+
+ [Browsable(false)]
+ [Label("Location")]
+ public virtual Location Location
+ {
+ get { return location; }
+ set { location = value; }
+ }
+
+ [Label("Location")]
+ [PropertyOrder(0, 1)]
+ public string LocationName
+ {
+ get { return this.Location.Name; }
+ }
+
+ [ReadOnly(true)]
+ [Format("F3")]
+ [Label("Detriment factor")]
+ [Category(ResultCategory)]
+ [PropertyOrder(2, 1)]
+ public double DetrimentFactor
+ {
+ get
+ {
+ // 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;
+ }
+ }
+
+ [Label("Soil profile")]
+ [Category(CalculationCategory)]
+ [PropertyOrder(2, 2)]
+ public string SoilProfileName
+ {
+ get
+ {
+ var res = "";
+ if (SoilGeometryProbability != null)
+ res = SoilGeometryProbability.SoilProfile.Name;
+ return res;
+ }
+ }
+
+ [ReadOnly(true)]
+ [Format("F3")]
+ [Label("Soil profile probability")]
+ [Category(CalculationCategory)]
+ [PropertyOrder(2, 3)]
+ public double SoilProfileProbability
+ {
+ get
+ {
+ var res = 0.0;
+ if (SoilGeometryProbability != null)
+ res = SoilGeometryProbability.Probability;
+ return res;
+ }
+ }
+
+ [ReadOnly(true)]
+ [Label("Load situation")]
+ [Category(CalculationCategory)]
+ [PropertyOrder(2, 4)]
+ public LoadSituation LoadSituation
+ {
+ get { return loadSituation; }
+ set { loadSituation = value; }
+ }
+
+ [ReadOnly(true)]
+ [Label("Dry sensitivity")]
+ [Category(CalculationCategory)]
+ [PropertyOrder(2, 5)]
+ public DikeDrySensitivity DikeDrySensitivity
+ {
+ get { return _dikeDrySensitivity; }
+ set { _dikeDrySensitivity = value; }
+ }
+
+ [ReadOnly(true)]
+ [Label("Hydraulic shortcut")]
+ [Category(CalculationCategory)]
+ [PropertyOrder(2, 6)]
+ public HydraulicShortcutType HydraulicShortcutType
+ {
+ get { return hydraulicShortcutType; }
+ set { hydraulicShortcutType = value; }
+ }
+
+ [ReadOnly(true)]
+ [Label("Uplift type")]
+ [Category(CalculationCategory)]
+ [PropertyOrder(2, 7)]
+ public UpliftType UpliftType
+ {
+ get { return upliftType; }
+ set { upliftType = value; }
+ }
+
+ [ReadOnly(true)]
+ [Label("Model Stability")]
+ [Category(CalculationCategory)]
+ [PropertyOrder(2, 8)]
+ [XmlOldName("ModelOption")]
+ public MStabModelType MstabModelOption
+ {
+ get { return mstabModelOption; }
+ set { mstabModelOption = value; }
+ }
+
+ [ReadOnly(true)]
+ [Label("Model Piping")]
+ [Category(CalculationCategory)]
+ [PropertyOrder(2, 8)]
+ public PipingModelType PipingModelOption
+ {
+ get { return pipingModelOption; }
+ set { pipingModelOption = value; }
+ }
+
+ [Browsable(false)]
+ [Category(CalculationCategory)]
+ public MStabParameters MStabParameters { get; set; }
+
+ [ReadOnly(true)]
+ [Label("Scenario")]
+ [PropertyOrder(0, 2)]
+ public ScenarioType ScenarioType
+ {
+ get { return scenarioType; }
+ set { scenarioType = value; }
+ }
+
+ [Browsable(false)]
+ [Label("File name")]
+ public string BaseFileName
+ {
+ get { return baseFileName; }
+ set { baseFileName = value; }
+ }
+
+ [Browsable(false)]
+ [Label("Input file")]
+ public string InputFile
+ {
+ get { return DamProject.ProjectWorkingPath + Path.DirectorySeparatorChar + baseFileName + ".sti"; }
+ }
+
+ [Browsable(false)]
+ [Label("Image file")]
+ public string ResultFile
+ {
+ get
+ {
+ const string wmfExtension = ".wmf";
+ string fullBaseFilename = DamProject.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;
+ }
+ }
+
+ [Browsable(false)]
+ [Label("Input file")]
+ public string PipingResultFile
+ {
+ // Note Bka: Path of piping is not based on the working dir but on assembly (Assembly.GetExecutingAssembly().Location)
+ get { return baseFileName + PipingCalculator.PipingFilenameExtension; }
+ }
+
+ [Label("Failure mechanism")]
+ public FailureMechanismSystemType FailureMechanismType
+ {
+ get { return failureMechanismType; }
+ set { failureMechanismType = value; }
+ }
+
+ [Browsable(false)]
+ [Label("Soil geometry")]
+ public SoilGeometryProbability SoilGeometryProbability
+ {
+ get { return soilGeometryProbability; }
+ set { soilGeometryProbability = value; }
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment/RWScenariosCalculation.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment/RWScenariosCalculation.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/Dikes Assessment/RWScenariosCalculation.cs (revision 274)
@@ -0,0 +1,602 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Text.RegularExpressions;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.RWScenarios;
+using Deltares.DamEngine.Data.Standard.Calculation;
+
+namespace Deltares.DamEngine.Calculators.Dikes_Assessment
+{
+ ///
+ /// 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;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ 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();
+
+ 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)
+ {
+ DataEventPublisher.InvokeWithoutPublishingEvents(() =>
+ {
+ 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));
+ }
+
+ }
+
+ 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);
+ }
+ }
+
+ ///
+ /// 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/branches/Initial Source/Deltares.DamEngine.Data/General/PolyLine.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/PolyLine.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/PolyLine.cs (revision 274)
@@ -0,0 +1,277 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2009 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 16-06-2009
+// Contains class PolyLine
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Deltares.DamEngine.Data.Geometry;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class PolyLineException : Exception
+ {
+ public PolyLineException(string message)
+ : base(message)
+ {
+ }
+ }
+
+ public class PolyLine where T : GeometryPoint, new()
+ {
+ protected IList points;
+
+ public PolyLine()
+ {
+ this.points = new List();
+ }
+
+ public virtual int Id { get; private set; }
+
+ public virtual string Name { get; set; }
+
+ public virtual IList Points { get { return this.points; } private set { this.points = value; } }
+
+ ///
+ /// Check if lines are equal
+ ///
+ ///
+ ///
+ public virtual bool Equals(PolyLine other)
+ {
+ bool isEqual = (other.Points.Count == this.Points.Count);
+ if (isEqual)
+ {
+ for (int pointIndex = 0; pointIndex < this.Points.Count; pointIndex++)
+ {
+ isEqual = isEqual && (this.Points[pointIndex].LocationEquals(other.Points[pointIndex]));
+ }
+ }
+ return isEqual;
+ }
+
+ ///
+ /// Check if line has a minimum of two points
+ ///
+ ///
+ public bool Exists()
+ {
+ return (this.Points.Count > 1);
+ }
+
+ ///
+ /// Check if all the points are in strict ascending X order
+ ///
+ ///
+ public bool IsXStrictAscending()
+ {
+ bool isStrictAscending = true;
+ for (int pointIndex = 0; pointIndex < this.Points.Count - 1; pointIndex++)
+ {
+ if (this.Points[pointIndex + 1].X <= this.Points[pointIndex].X)
+ {
+ isStrictAscending = false;
+ break;
+ }
+ }
+ return isStrictAscending;
+ }
+
+ ///
+ /// Check if all the points are in ascending X order
+ ///
+ ///
+ public bool IsXAscending()
+ {
+ bool isAscending = true;
+ for (int pointIndex = 0; pointIndex < this.Points.Count - 1; pointIndex++)
+ {
+ if (this.Points[pointIndex + 1].X < this.Points[pointIndex].X)
+ {
+ isAscending = false;
+ break;
+ }
+ }
+ return isAscending;
+ }
+
+ ///
+ /// Gets point at X if present within tolerance or null if not present.
+ ///
+ ///
+ public T GetPointAtX(double X, double tolerance)
+ {
+ return (from T point in this.points
+ where Math.Abs(point.X - X) < tolerance
+ select point).FirstOrDefault();
+ }
+
+ private T InsertPointAtX(double X)
+ {
+ T newPoint = new T();
+ newPoint.X = X;
+ try
+ {
+ T pointAfter = (from T point in this.points
+ where point.X > X
+ select point).First();
+
+ this.points.Insert(this.points.IndexOf(pointAfter), newPoint);
+ }
+ catch
+ {
+ this.points.Add(newPoint);
+ }
+ return newPoint;
+ }
+
+ ///
+ /// Gets point at X if present within tolerance; creates one there if not present.
+ ///
+ ///
+ public T EnsurePointAtX(double X, double tolerance)
+ {
+ T point = GetPointAtX(X, tolerance);
+ if (point == null)
+ {
+ point = InsertPointAtX(X);
+ }
+ return point;
+ }
+
+ public double ZFromX(double X)
+ {
+ if (!this.IsXAscending())
+ {
+ throw new PolyLineException("Interpolation only possible with ascending polyline");
+ }
+
+ double valueZ = 0.0;
+
+ // Less then first X
+ if (X <= this.Points[0].X)
+ {
+ valueZ = this.Points[0].Z;
+ }
+ // More then last X
+ else if (X >= this.Points[this.Points.Count - 1].X)
+ {
+ valueZ = this.Points[this.Points.Count - 1].Z;
+ }
+ else
+ {
+ // X is inside boundaries
+ for (int pointIndex = 0; pointIndex < this.Points.Count - 1; pointIndex++)
+ {
+ if ((X > this.Points[pointIndex].X) && (X <= this.Points[pointIndex + 1].X))
+ {
+ // interpolate in this section
+ double fractionX = (X - this.Points[pointIndex].X) / (this.Points[pointIndex + 1].X - this.Points[pointIndex].X);
+ valueZ = this.Points[pointIndex].Z + fractionX * (this.Points[pointIndex + 1].Z - this.Points[pointIndex].Z);
+ break;
+ }
+ }
+ }
+ return valueZ;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder stringBuilder = new StringBuilder();
+
+ stringBuilder.Append(this.Name);
+ stringBuilder.Append(" [");
+ foreach (T point in this.points)
+ {
+ if (this.points.IndexOf(point) > 0)
+ stringBuilder.Append(", ");
+ stringBuilder.Append(point.ToString());
+ }
+ stringBuilder.Append("]");
+
+ return stringBuilder.ToString();
+ }
+
+ public virtual void CopyPoints(PolyLine polyLine)
+ {
+ foreach (T point in polyLine.Points)
+ {
+ points.Add(point);
+ }
+ }
+
+ ///
+ /// Deletes the coinsiding points.
+ ///
+ /// The tolerance.
+ public virtual void DeleteCoinsidingPoints(double tolerance)
+ {
+ // First build a list of indices of points that have to be removed (from end of list to start)
+ var indicesToDelete = new List();
+ for (int pointIndex = Points.Count - 1; pointIndex > 0; pointIndex--)
+ {
+ for (int i = pointIndex - 1; i >= 0; i--)
+ {
+ if (Points[pointIndex].LocationEquals(Points[i], tolerance))
+ {
+ indicesToDelete.Add(i);
+ }
+ }
+ }
+
+ // Remove duplicate points beginning from the end
+ for (int index = 0; index < indicesToDelete.Count; index++)
+ {
+ Points.RemoveAt(indicesToDelete[index]);
+ }
+
+ }
+
+ public virtual void DeleteCoinsidingPoints()
+ {
+ const double defaultTolerance = 0.001;
+ DeleteCoinsidingPoints(defaultTolerance);
+ }
+
+ public virtual double MinZ()
+ {
+ if (this.Points.Count > 1)
+ {
+ double minZ = this.points.First().Z;
+ foreach (T point in this.points)
+ {
+ minZ = Math.Min(minZ, point.Z);
+ }
+ return minZ;
+ }
+ else
+ {
+ return 0.0;
+ }
+ }
+
+ public virtual double MaxZ()
+ {
+ if (this.Points.Count > 1)
+ {
+ double maxZ = this.points.First().Z;
+ foreach (T point in this.points)
+ {
+ maxZ = Math.Max(maxZ, point.Z);
+ }
+ return maxZ;
+ }
+ else
+ {
+ return 0.0;
+ }
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/TranslateInfo.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/TranslateInfo.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/TranslateInfo.cs (revision 274)
@@ -0,0 +1,74 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard.Language
+{
+ ///
+ /// class TranslateInfo
+ ///
+ public class TranslateInfo
+ {
+ private readonly Dictionary languageTable
+ = new Dictionary();
+
+ private string languageType = "";
+
+ ///
+ /// Gets or sets the identifier.
+ ///
+ ///
+ /// The identifier.
+ ///
+ public string Id
+ {
+ get
+ {
+ return languageType;
+ }
+ set
+ {
+ languageType = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the with the specified language.
+ ///
+ ///
+ /// The .
+ ///
+ /// The language.
+ ///
+ public string this[LanguageType language]
+ {
+ get
+ {
+ return languageTable[language];
+ }
+ set
+ {
+ languageTable[language] = value;
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Point2D.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Point2D.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Point2D.cs (revision 274)
@@ -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/branches/Initial Source/Deltares.DamEngine.Data/General/DAMEnumerations.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DAMEnumerations.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DAMEnumerations.cs (revision 274)
@@ -0,0 +1,375 @@
+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/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs (revision 274)
@@ -0,0 +1,202 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.
+ private 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/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/LanguageTypeHelper.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/LanguageTypeHelper.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/LanguageTypeHelper.cs (revision 274)
@@ -0,0 +1,72 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard.Language
+{
+ ///
+ /// class LanguageTypeHelper
+ ///
+ public static class LanguageTypeHelper
+ {
+ ///
+ /// The english string
+ ///
+ private const string englishString = "en-US";
+ ///
+ /// The dutch string
+ ///
+ private const string dutchString = "nl-NL";
+
+ ///
+ /// Gets the language string.
+ ///
+ /// The type.
+ ///
+ public static string GetLanguageString(this LanguageType type)
+ {
+ switch (type)
+ {
+ case LanguageType.Dutch:
+ return dutchString;
+
+ case LanguageType.English:
+ return englishString;
+
+ default:
+ return string.Empty;
+ }
+ }
+
+ ///
+ /// Gets the short language string.
+ ///
+ /// The type.
+ ///
+ public static string GetShortLanguageString(this LanguageType type)
+ {
+ var longString = type.GetLanguageString();
+ var dashIndex = longString.IndexOf("-", StringComparison.Ordinal);
+ return longString.Substring(dashIndex + 1);
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Validation/ValidateAttribute.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Validation/ValidateAttribute.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Validation/ValidateAttribute.cs (revision 274)
@@ -0,0 +1,38 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard.Validation
+{
+ ///
+ /// class ValidateAttribute
+ ///
+ ///
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
+ public class ValidateAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ValidateAttribute() {}
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (revision 274)
@@ -0,0 +1,141 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}
+ Library
+ Properties
+ Deltares.DamEngine.Data
+ Deltares.DamEngine.Data
+ v4.5
+ 512
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\x86\Release\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Calculation/ICalculation.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Calculation/ICalculation.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Calculation/ICalculation.cs (revision 274)
@@ -0,0 +1,43 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Delta Shell Light Library.
+//
+// The Delta Shell Light Library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU 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 General Public License for more details.
+//
+// You should have received a copy of the GNU 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.Standard.Calculation
+{
+ public enum CalculationResult
+ {
+ NoRun = -1,
+ Succeeded = 0,
+ NoInput = 1,
+ NoLicense = 2,
+ UserAbort = 3,
+ InvalidInputStructure = 4,
+ InvalidInputData = 5,
+ RunFailed = 6,
+ UnexpectedError = 7
+ }
+
+ public interface ICalculation
+ {
+ CalculationResult RegisterProgress(ProgressDelegate progressDelegate);
+ CalculationResult RegisterGetValues(GetValuesDelegate getValuesDelegate);
+ CalculationResult RegisterSetValues(SetValuesDelegate setValuesDelegate);
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/ShearStrengthModel.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/ShearStrengthModel.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/ShearStrengthModel.cs (revision 274)
@@ -0,0 +1,74 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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 ShearStrengthModel
+ {
+ ///
+ /// The none
+ ///
+ None = 1,
+
+ ///
+ /// The c phi
+ ///
+ CPhi = 2,
+
+ ///
+ /// The stress table
+ ///
+ StressTable = 3,
+
+ ///
+ /// The pseudo values
+ ///
+ PseudoValues = 4,
+
+ ///
+ /// The cu measured
+ ///
+ CuMeasured = 5,
+
+ ///
+ /// The cu calculated
+ ///
+ CuCalculated = 6,
+
+ ///
+ /// The cu gradient
+ ///
+ CuGradient = 7,
+
+ ///
+ /// The cu calculated yield
+ ///
+ CuCalculatedYield = 8,
+
+ ///
+ /// CPhi or CuCalculated dependent if below or above phreatic line
+ ///
+ CPhiOrCuCalculated = 9
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Gauges/GaugePLLine.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Gauges/GaugePLLine.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Gauges/GaugePLLine.cs (revision 274)
@@ -0,0 +1,63 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2010 Deltares. All rights reserved.
+//
+// B.S.T. The
+// tom.the@deltares.nl
+// 04-11-2010
+// n.a.
+//-----------------------------------------------------------------------
+
+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/branches/Initial Source/Deltares.DamEngine.Data/General/DikeJob.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DikeJob.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DikeJob.cs (revision 274)
@@ -0,0 +1,51 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2009 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 16-2-2011
+// n.a.
+//-----------------------------------------------------------------------
+
+using System.Xml.Serialization;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class DikeJob : CompositeJob
+ {
+ public DikeJob()
+ {
+ }
+
+ public DikeJob(object subject) : base(subject)
+ {
+ }
+
+ [XmlIgnore]
+ public Dike Dike
+ {
+ get
+ {
+ return this.Subject as Dike;
+ }
+ set
+ {
+ this.Subject = value;
+ }
+ }
+
+ public bool AreAllLocationWaterLevelTimeSeriesAssigned()
+ {
+ bool areAssigned = true;
+ foreach (DamJob damJob in Jobs)
+ {
+ if (damJob.GetType() == typeof(LocationJob))
+ {
+ areAssigned = areAssigned && (((LocationJob)damJob).WaterLevelTimeSerie != null);
+ }
+ }
+ return areAssigned;
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile.cs (revision 274)
@@ -0,0 +1,77 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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 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/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Line.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Line.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Line.cs (revision 274)
@@ -0,0 +1,204 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/LocalizationManager.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/LocalizationManager.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Language/LocalizationManager.cs (revision 274)
@@ -0,0 +1,255 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Xml;
+
+namespace Deltares.DamEngine.Data.Standard.Language
+{
+ ///
+ /// Class LocalizationManager
+ ///
+ public class LocalizationManager
+ {
+ ///
+ /// The default language
+ ///
+ private const LanguageType defaultLanguage = LanguageType.English;
+
+ private static LanguageType currentLanguageType = defaultLanguage;
+ private static CultureInfo currentCultureInfo = new CultureInfo(defaultLanguage.GetLanguageString());
+
+ private static readonly Dictionary> Translations
+ = new Dictionary>();
+
+ private static readonly Dictionary> TranslationLists
+ = new Dictionary>();
+
+ private static readonly List DirtyAssemblies
+ = new List();
+
+ ///
+ /// Gets or sets the current language
+ ///
+ public static LanguageType CurrentLanguage
+ {
+ get
+ {
+ return currentLanguageType;
+ }
+ set
+ {
+ if (value != currentLanguageType || currentCultureInfo == null)
+ {
+ currentLanguageType = value;
+ currentCultureInfo = new CultureInfo(value.GetLanguageString());
+ }
+ }
+ }
+
+ ///
+ /// Gets the translated text.
+ ///
+ /// The type.
+ /// The identifier.
+ ///
+ public static string GetTranslatedText(Type type, string id)
+ {
+ if (type == null || string.IsNullOrEmpty(id))
+ {
+ return id;
+ }
+ var assembly = type.Assembly;
+ if (!Translations.ContainsKey(assembly))
+ {
+ CreateTables(assembly);
+ LoadLanguage(assembly);
+ }
+
+ if (Translations[assembly].ContainsKey(id))
+ {
+ return Translations[assembly][id][currentLanguageType];
+ }
+
+ if (!id.Equals(""))
+ {
+ UpdateTranslation(type, id, id);
+ }
+ return id;
+ }
+
+ ///
+ /// Gets the translated text.
+ ///
+ /// The target object.
+ /// The identifier.
+ ///
+ public static string GetTranslatedText(object targetObject, string id)
+ {
+ return targetObject == null ?
+ id : GetTranslatedText(targetObject.GetType(), id);
+ }
+
+ ///
+ /// Updates the translation.
+ ///
+ /// The type.
+ /// The identifier.
+ /// The english.
+ private static void UpdateTranslation(Type type, string identifier, string english)
+ {
+ if (!Translations.ContainsKey(type.Assembly))
+ {
+ CreateTables(type.Assembly);
+ LoadLanguage(type.Assembly);
+ }
+
+ if (!Translations[type.Assembly].ContainsKey(identifier))
+ {
+ var translateInfo = new TranslateInfo
+ {
+ Id = identifier
+ };
+
+ foreach (LanguageType languageType in Enum.GetValues(typeof(LanguageType)))
+ {
+ if (languageType == LanguageType.English)
+ {
+ translateInfo[languageType] = english;
+ }
+ else
+ {
+ translateInfo[languageType] = languageType.GetShortLanguageString() + "-" + english;
+ }
+ }
+ Translations[type.Assembly][identifier] = translateInfo;
+ TranslationLists[type.Assembly].Add(translateInfo);
+ }
+ else
+ {
+ var translateInfo = Translations[type.Assembly][identifier];
+ foreach (LanguageType languageType in Enum.GetValues(typeof(LanguageType)))
+ {
+ if (languageType == LanguageType.English)
+ {
+ translateInfo[languageType] = english;
+ }
+ else
+ {
+ var translation = translateInfo[languageType];
+ var prefix = languageType.GetShortLanguageString() + "-";
+ var defaultTranslation = prefix + english;
+ if (string.IsNullOrEmpty(translation) || translation == defaultTranslation)
+ {
+ translateInfo[languageType] = prefix + english;
+ }
+ else if (!translation.StartsWith(prefix))
+ {
+ translateInfo[languageType] = translation;
+ }
+ }
+ }
+ }
+
+ if (!DirtyAssemblies.Contains(type.Assembly))
+ {
+ DirtyAssemblies.Add(type.Assembly);
+ }
+ }
+
+ private static void LoadLanguage(Assembly assembly)
+ {
+ var translationFiles = assembly
+ .GetManifestResourceNames()
+ .Where(res => res.EndsWith("Translations.xml"));
+
+ foreach (var resourceName in translationFiles)
+ {
+ var resource = assembly.GetManifestResourceStream(resourceName);
+ LoadDictionary(assembly, resource);
+ }
+ }
+
+ private static void LoadDictionary(Assembly assembly, Stream translatedXmlFilePath)
+ {
+ CreateTables(assembly);
+ var translationsTable = Translations[assembly];
+
+ var reader = XmlReader.Create(translatedXmlFilePath);
+ var xmlDocument = new XmlDocument();
+ xmlDocument.Load(reader);
+ xmlDocument.Normalize();
+ var xmlNodeList = xmlDocument.GetElementsByTagName(@"Translation");
+
+ //Validating the translated xml file against schema definition
+ //string errorString = "";
+ //XmlSchemaValidator.ValidXmlDoc(this.translatedXmlFilePath, this.xsdFilePath, ref errorString);
+
+ foreach (XmlNode node in xmlNodeList)
+ {
+ if (node.Attributes == null)
+ {
+ throw new ArgumentException("node has no attributes");
+ }
+
+ var attr = node.Attributes["ID"];
+ var id = attr.Value;
+ var translateInfo = new TranslateInfo
+ {
+ Id = id
+ };
+
+ foreach (LanguageType type in Enum.GetValues(typeof(LanguageType)))
+ {
+ var translation = node.Attributes[type.GetLanguageString()].Value;
+
+ if (translation != null)
+ {
+ translateInfo[type] = translation;
+ }
+ }
+
+ translationsTable[id] = translateInfo;
+ TranslationLists[assembly].Add(translateInfo);
+ }
+
+ reader.Close();
+
+ Translations[assembly] = translationsTable;
+ }
+
+ private static void CreateTables(Assembly assembly)
+ {
+ if (Translations.ContainsKey(assembly))
+ {
+ return;
+ }
+
+ Translations[assembly] = new Dictionary();
+ TranslationLists[assembly] = new List();
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Validation/ValidationResultType.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Validation/ValidationResultType.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/Validation/ValidationResultType.cs (revision 274)
@@ -0,0 +1,46 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard.Validation
+{
+ ///
+ ///
+ ///
+ public enum ValidationResultType
+ {
+ ///
+ /// The debug
+ ///
+ Debug,
+ ///
+ /// The information
+ ///
+ Info,
+ ///
+ /// The warning
+ ///
+ Warning,
+ ///
+ /// The error
+ ///
+ Error
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/PlLines/PL1Line.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/PlLines/PL1Line.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/PlLines/PL1Line.cs (revision 274)
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2010 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 18-05-2010
+// Object representing a freatic line
+//-----------------------------------------------------------------------
+
+using System;
+using Deltares.DamEngine.Data.Geometry;
+
+namespace Deltares.DamEngine.Data.General.PlLines
+{
+ public class PL1LineException : Exception
+ {
+ public PL1LineException(string message) : base(message)
+ {
+ }
+ }
+
+ public class PL1Line : GeometryPointString
+ {
+ public void Assign(PL1Line pl1Line)
+ {
+ this.Points.Clear();
+
+ foreach (GeometryPoint point in pl1Line.Points)
+ {
+ GeometryPoint newPoint = (GeometryPoint) point.Clone();
+ this.Points.Add(newPoint);
+ }
+ }
+
+ public PL1Line Clone()
+ {
+ var newPL1Line = new PL1Line();
+
+ newPL1Line.Assign(this);
+
+ return newPL1Line;
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/WaterBoard.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/WaterBoard.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/WaterBoard.cs (revision 274)
@@ -0,0 +1,179 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2011 Deltares. All rights reserved.
+//
+// J. Bokma
+// j.bokma@deltares.nl
+// 02-02-2011
+// n.a.
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.Standard.Language;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class WaterBoard : IDisposable
+ {
+ 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;
+ }
+
+ public void Dispose()
+ {
+ foreach (var dike in Dikes)
+ {
+ dike.Dispose();
+ }
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Gauges/Gauge.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Gauges/Gauge.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Gauges/Gauge.cs (revision 274)
@@ -0,0 +1,18 @@
+using System;
+
+namespace Deltares.DamEngine.Data.General.Gauges
+{
+ public class Gauge
+ {
+ public virtual string Name { get; set; }
+ public virtual Location Location{ get; set; }
+ public virtual double LocalX { get; set; }
+
+ public double? Value { get; set; }
+
+ public override string ToString()
+ {
+ return String.Format("{0} @ Location {1} | Local X={2}", this.Name, this.Location != null ? this.Location.Name : "?", this.LocalX);
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Routines2D.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Routines2D.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/Routines2D.cs (revision 274)
@@ -0,0 +1,612 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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
+ {
+ private 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;
+ }
+
+ ///
+ /// 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.
+ ///
+ ///
+ ///
+ ///
+ ///
+ private 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/branches/Initial Source/Deltares.DamEngine.sln
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.sln (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.sln (revision 274)
@@ -0,0 +1,44 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deltares.DamEngine.Data", "Deltares.DamEngine.Data\Deltares.DamEngine.Data.csproj", "{B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deltares.DamEngine.Calculators", "Deltares.DamEngine.Calculators\Deltares.DamEngine.Calculators.csproj", "{E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Debug|Mixed Platforms.Build.0 = Debug|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|Any CPU.ActiveCfg = Release|Any CPU
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Release|Mixed Platforms.Build.0 = Release|x86
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Release|x86.ActiveCfg = Release|x86
+ {B7A49C1A-1C91-4D72-ABA9-9FBAC2509D8E}.Release|x86.Build.0 = Release|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Debug|Mixed Platforms.Build.0 = Debug|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|Any CPU.ActiveCfg = Release|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Release|Mixed Platforms.Build.0 = Release|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Release|x86.ActiveCfg = Release|x86
+ {E943B1D5-FAFA-4AFE-9071-F8B22CF612EA}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Design/CsvExportData.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Design/CsvExportData.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Design/CsvExportData.cs (revision 274)
@@ -0,0 +1,2542 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2010 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 05-10-2010
+// Data definition for results export to csv
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Xml.Serialization;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Data.General;
+
+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, IVisibleEnabled, IGeographicPoint
+ {
+ 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 string nwoId;
+ private int nwoResultIndex;
+ private double? locationXrdStart;
+ private double? locationYrdStart;
+ private double? locationZrdStart;
+ private double? locationXrdEnd;
+ private double? locationYrdEnd;
+ private 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;
+ }
+ }
+
+ [Browsable(false)]
+ public StabilityKernelType SelectedStabilityKernelType
+ {
+ get { return selectedStabilityKernelType; }
+ set { selectedStabilityKernelType = value; }
+ }
+
+ [Label("Number of iterations")]
+ [ReadOnly(true)]
+ public int NumberOfIterations
+ {
+ get { return numberOfIterations; }
+ set { numberOfIterations = value; }
+ }
+
+ [Browsable(false)]
+ [Label("Image file")]
+ public string ResultFile
+ {
+ get
+ {
+ if (!String.IsNullOrEmpty(BaseFileName))
+ {
+ const string wmfExtension = ".wmf";
+ string fullBaseFilename = DamProject.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 "";
+ }
+ }
+
+ [Browsable(false)]
+ [Label("Input file")]
+ public string InputFile
+ {
+ get
+ {
+ if (!String.IsNullOrEmpty(BaseFileName))
+ {
+ string fileExtension = ".sti";
+ if (selectedStabilityKernelType != StabilityKernelType.DamClassic)
+ {
+ fileExtension = ".dsx";
+ }
+ string fullBaseFilename = DamProject.ProjectWorkingPath;
+ if (CalculationSubDir != "")
+ {
+ fullBaseFilename = Path.Combine(fullBaseFilename, CalculationSubDir);
+ }
+ fullBaseFilename = fullBaseFilename + Path.DirectorySeparatorChar + BaseFileName;
+ string fullFilename = fullBaseFilename + fileExtension;
+ return fullFilename;
+ }
+ return "";
+ }
+ }
+
+ [Browsable(false)]
+ [Label("Input file")]
+ 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 = DamProject.ProjectWorkingPath;
+ if (CalculationSubDir != "")
+ {
+ fullBaseFilename = Path.Combine(fullBaseFilename, CalculationSubDir);
+ }
+ fullBaseFilename = fullBaseFilename + Path.DirectorySeparatorChar + BaseFileName;
+ string fullFilename = fullBaseFilename + txtExtension;
+ return fullFilename;
+ }
+ return "";
+ }
+ }
+
+ [Label("Analysis")]
+ [PropertyOrder(1, 2)]
+ [ReadOnly(true)]
+ public AnalysisType AnalysisType
+ {
+ get { return analysisType; }
+ set { analysisType = value; }
+ }
+
+ [Label("Probabilistic")]
+ [PropertyOrder(1, 3)]
+ [ReadOnly(true)]
+ public ProbabilisticType ProbabilisticType
+ {
+ get { return probabilisticType; }
+ set { probabilisticType = value; }
+ }
+
+ [Browsable(false)]
+ public DamFailureMechanismeCalculationSpecification DamFailureMechanismeCalculation
+ {
+ get { return damFailureMechanismeCalculationSpecification; }
+ set { damFailureMechanismeCalculationSpecification = value; }
+ }
+
+ [CsvExportColumn("id", 1)]
+ [Browsable(false)]
+ public string ID
+ {
+ get { return this.id; }
+ }
+
+ [CsvExportColumn("DikeName", 2)]
+ [Browsable(false)]
+ [Label("Dike")]
+ public string DikeName
+ {
+ get { return dike.Name; }
+ }
+
+ [CsvExportColumn("Calculation", 3)]
+ [Browsable(false)]
+ public string Calculation
+ {
+ get { return this.damFailureMechanismeCalculationSpecification != null ? this.damFailureMechanismeCalculationSpecification.ToString() : ""; }
+ }
+
+ [CsvExportColumn("Scenario", 4)]
+ [Browsable(false)]
+ public string ScenarioName
+ {
+ get { return this.Scenario.LocationScenarioID; }
+ }
+
+ [CsvExportColumn("LocationName", 5)]
+ [Label("Location")]
+ [PropertyOrder(0, 1)]
+ [ReadOnly(true)]
+ public string LocationName
+ {
+ get { return this.Scenario.Location.Name; }
+ }
+
+ [Browsable(false)]
+ public int LocationScenarioCount
+ {
+ get { return this.Scenario.Location.Scenarios.Count; }
+ }
+
+ [Label("Scenario")]
+ [PropertyOrder(0, 2)]
+ [ReadOnly(true)]
+ public string ScenarioDefinitionName
+ {
+ get { return this.Scenario.LocationScenarioID + " of " + this.LocationScenarioCount.ToString(); }
+ }
+
+ [Label("Calculation result")]
+ [PropertyOrder(0, 3)]
+ public CalculationResult CalculationResult
+ {
+ get
+ {
+ return calculationResult;
+ }
+ set
+ {
+ calculationResult = value;
+ }
+ }
+
+ [Label("Message")]
+ [PropertyOrder(7,1)]
+ [ReadOnly(true)]
+ public string ResultMessage
+ {
+ get { return resultMessage; }
+ set { resultMessage = value; }
+ }
+
+ [CsvExportColumn("X", 6)]
+ [Label("Global X-coordinate")]
+ [Format("F3")]
+ [PropertyOrder(1, 0)]
+ [Unit(UnitType.Length)]
+ [XmlIgnore]
+ [ReadOnly(true)]
+ public double X
+ {
+ get
+ {
+ return (this.Scenario != null) ? this.Scenario.Location.XRd : 0.0;
+ }
+ set
+ {
+ if (this.Scenario != null)
+ {
+ this.Scenario.Location.XRd = value;
+ }
+ }
+ }
+
+ [CsvExportColumn("Y", 7)]
+ [Label("Global Y-coordinate")]
+ [Format("F3")]
+ [PropertyOrder(1, 1)]
+ [Unit(UnitType.Length)]
+ [XmlIgnore]
+ [ReadOnly(true)]
+ public double Y
+ {
+ get
+ {
+ return (this.Scenario != null) ? this.Scenario.Location.YRd : 0.0;
+ }
+ set
+ {
+ if (this.Scenario != null)
+ {
+ this.Scenario.Location.YRd = value;
+ }
+ }
+ }
+
+ [CsvExportColumn("LocationScenarioId", 8)]
+ [Browsable(false)]
+ public string LocationScenarioId
+ {
+ get { return this.Scenario.LocationScenarioID; }
+ }
+
+ [Label("River level")]
+ [CsvExportColumn("RiverLevel", 9)]
+ [PropertyOrder(2, 12)]
+ [Format("F3")]
+ [ReadOnly(true)]
+ public double? RiverLevel
+ {
+ get { return this.Scenario.RiverLevel; }
+ }
+
+ [Label("River level low")]
+ [CsvExportColumn("RiverLevelLow", 10)]
+ [PropertyOrder(2, 13)]
+ [Format("F3")]
+ [ReadOnly(true)]
+ public double? RiverLevelLow
+ {
+ get { return this.Scenario.RiverLevelLow; }
+ }
+
+ [Label("Dike table height")]
+ [CsvExportColumn("DikeTableHeight", 11)]
+ [PropertyOrder(2, 14)]
+ [Format("F3")]
+ [ReadOnly(true)]
+ public double? DikeTableHeight
+ {
+ get { return this.Scenario.DikeTableHeight; }
+ }
+
+ [Label("Slope damping factor")]
+ [CsvExportColumn("DikeTableHeight", 12)]
+ [PropertyOrder(2, 15)]
+ [Format("F3")]
+ [ReadOnly(true)]
+ public double? SlopeDampingPiezometricHeightPolderSide
+ {
+ get { return this.Scenario.Location.SlopeDampingPiezometricHeightPolderSide; }
+ }
+
+ [CsvExportColumn("CurrentDikeHeight", 13)]
+ [Browsable(false)]
+ public double? CurrentDikeHeight
+ {
+ get { return this.Scenario.Location.SurfaceLine2.GetDikeHeight(); }
+ }
+
+ [CsvExportColumn("CurrentDikeToeAtPolderX", 14)]
+ [Browsable(false)]
+ public double? CurrentDikeToeAtPolderX
+ {
+ get
+ {
+ double? x = null;
+ GeometryPoint point = this.Scenario.Location.SurfaceLine2.GetDikeToeInward();
+ if (point != null)
+ x = point.X;
+ return x;
+ }
+ }
+
+ [CsvExportColumn("CurrentDikeToeAtPolderZ", 15)]
+ [Browsable(false)]
+ 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);
+ }
+
+ [CsvExportColumn("StabilityProfileName", 16)]
+ [Label("Stability profile")]
+ [Browsable(false)]
+ public string StabilityProfileName
+ {
+ get { return GetSoilProfileName(FailureMechanismSystemType.StabilityInside); }
+ }
+
+ [CsvExportColumn("StabilityProfileProbability", 17)]
+ [Label("Stability probability")]
+ [Format("F3")]
+ [Unit(UnitType.Fractions)]
+ [Browsable(false)]
+ public double? StabilityProfileProbability
+ {
+ get { return GetSoilProfileProbability(FailureMechanismSystemType.StabilityInside); }
+ }
+
+ [CsvExportColumn("PipingProfileName", 18)]
+ [Label("Piping profile")]
+ [Browsable(false)]
+ public string PipingProfileName
+ {
+ get { return GetSoilProfileName(FailureMechanismSystemType.Piping); }
+ }
+
+ [CsvExportColumn("PipingProfileProbability", 19)]
+ [Label("Piping probability")]
+ [Format("F3")]
+ [Unit(UnitType.Fractions)]
+ [Browsable(false)]
+ public double? PipingProfileProbability
+ {
+ get { return GetSoilProfileProbability(FailureMechanismSystemType.Piping); }
+ }
+
+ [CsvExportColumn("CurrentDikeLength", 20)]
+ [Browsable(false)]
+ public double? CurrentDikeLength
+ {
+ get { return this.Scenario.Location.SurfaceLine2.GetDikeLength(); }
+ }
+
+ [CsvExportColumn("StabilityToeAtPolderX", 21)]
+ [Label("Stability toe polder")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [Browsable(false)]
+ public double? StabilityToeAtPolderX
+ {
+ get
+ {
+ if (this.redesignedSurfaceLineStability == null)
+ return null;
+
+ GeometryPoint point = this.redesignedSurfaceLineStability.GetDikeToeInward();
+ if (point != null)
+ return point.X;
+ else
+ return null;
+ }
+ }
+
+ [CsvExportColumn("StabilityToeAtPolderZ", 22)]
+ [Label("Height stability toe polder")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [Browsable(false)]
+ public double? StabilityToeAtPolderZ
+ {
+ get
+ {
+ if (this.redesignedSurfaceLineStability == null)
+ return null;
+
+ GeometryPoint point = this.redesignedSurfaceLineStability.GetDikeToeInward();
+ if (point != null)
+ return point.Z;
+ else
+ return null;
+ }
+ }
+
+ [CsvExportColumn("StabilityShoulderHeight", 23)]
+ [Label("Stability shoulder height")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [Browsable(false)]
+ 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;
+ }
+ }
+
+ [CsvExportColumn("StabilitySafetyFactor", 24)]
+ [Label("Stability safety factor")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? StabilitySafetyFactor
+ {
+ get { return this.safetyFactorStability; }
+ set { this.safetyFactorStability = value; }
+ }
+
+ [CsvExportColumn("StabilityFailureProbability", 25)]
+ [Label("Stability failure probability")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? StabilityFailureProbability
+ {
+ get { return this.failureProbabilityStability; }
+ set { this.failureProbabilityStability = value; }
+ }
+
+ [CsvExportColumn("RequiredSafetyFactorStabilityInnerSlope", 26)]
+ [Label("Required safety factor stability inside")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? RequiredSafetyFactorStabilityInnerSlope
+ {
+ get { return this.Scenario.RequiredSafetyFactorStabilityInnerSlope;}
+ }
+
+ [CsvExportColumn("RequiredSafetyFactorStabilityOuterSlope", 27)]
+ [Label("Required safety factor stability outside")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? RequiredSafetyFactorStabilityOuterSlope
+ {
+ get { return this.Scenario.RequiredSafetyFactorStabilityOuterSlope; }
+ }
+
+ [CsvExportColumn("RequiredSafetyFactorPiping", 28)]
+ [Label("Required safety factor piping")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? RequiredSafetyFactorPiping
+ {
+ get { return this.Scenario.RequiredSafetyFactorPiping; }
+ }
+
+ [CsvExportColumn("PipingToeAtPolderX", 29)]
+ [Label("Piping toe")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [Browsable(false)]
+ public double? PipingToeAtPolderX
+ {
+ get
+ {
+ if (this.redesignedSurfaceLinePiping == null)
+ return null;
+
+ GeometryPoint point = this.redesignedSurfaceLinePiping.GetDikeToeInward();
+ if (point != null)
+ return point.X;
+ else
+ return null;
+ }
+ }
+
+ [CsvExportColumn("PipingToeAtPolderZ", 30)]
+ [Label("Height Piping toe")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [Browsable(false)]
+ public double? PipingToeAtPolderZ
+ {
+ get
+ {
+ if (this.redesignedSurfaceLinePiping == null)
+ return null;
+
+ GeometryPoint point = this.redesignedSurfaceLinePiping.GetDikeToeInward();
+ if (point != null)
+ return point.Z;
+ else
+ return null;
+ }
+ }
+
+ [CsvExportColumn("PipingShoulderHeight", 31)]
+ [Label("Piping shoulder height")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [Browsable(false)]
+ 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;
+ }
+ }
+
+ [CsvExportColumn("PipingFailureProbability", 32)]
+ [Label("Piping failure probability")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? PipingFailureProbability
+ {
+ get { return this.failureProbabilityPiping; }
+ set { this.failureProbabilityPiping = value; }
+ }
+
+ [Label("Required piping failure probability")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? RequiredFailureProbabilityPiping
+ {
+ get { return this.Scenario.RequiredProbabilityOfFailurePiping; }
+ }
+
+ [CsvExportColumn("DikeLength", 33)]
+ [Label("Dike length")]
+ [Format("F3")]
+ [PropertyOrder(4, 1)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ 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;
+ }
+ }
+
+ [CsvExportColumn("Zone1SafetyFactorStability", 34)]
+ [Label("Zone 1 safety factor")]
+ [Format("F3")]
+ [PropertyOrder(3, 1)]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ public double? Zone1SafetyFactorStability
+ {
+ get { return this.zone1SafetyFactorStability; }
+ set { this.zone1SafetyFactorStability = value; }
+ }
+
+ [Label("Zone 1 entry point (X-local)")]
+ [Format("F3")]
+ [PropertyOrder(3, 2)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? LocalZone1EntryPointX
+ {
+ get { return localZone1EntryPointX; }
+ set { localZone1EntryPointX = value; }
+ }
+
+ [CsvExportColumn("Zone1EntryPointX", 36)]
+ [Label("Zone 1 entry point (X-global)")]
+ [Format("F3")]
+ [PropertyOrder(3, 3)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? Zone1EntryPointX
+ {
+ get
+ {
+ if (this.LocalZone1EntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone1EntryPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [CsvExportColumn("Zone1EntryPointY", 37)]
+ [Label("Zone 1 entry point (Y-global)")]
+ [Format("F3")]
+ [PropertyOrder(3, 4)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? Zone1EntryPointY
+ {
+ get
+ {
+ if (this.LocalZone1EntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone1EntryPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ [CsvExportColumn("Zone1EntryPointZ", 38)]
+ [Label("Zone 1 entry point (Z)")]
+ [Format("F3")]
+ [PropertyOrder(3, 5)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? Zone1EntryPointZ
+ {
+ get
+ {
+ if (this.LocalZone1EntryPointX == null)
+ return null;
+ if (redesignedSurfaceLineStability == null)
+ return null;
+ return this.redesignedSurfaceLineStability.Geometry.GetZAtX(this.LocalZone1EntryPointX.Value);
+ }
+ }
+
+ [CsvExportColumn("LocalZone1ExitPointX", 39)]
+ [Label("Zone 1 exit point (X-local)")]
+ [Format("F3")]
+ [PropertyOrder(3, 6)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? LocalZone1ExitPointX
+ {
+ get { return localZone1ExitPointX; }
+ set { localZone1ExitPointX = value; }
+ }
+
+ [CsvExportColumn("Zone1ExitPointX", 40)]
+ [Label("Zone 1 exit point (X-global)")]
+ [Format("F3")]
+ [PropertyOrder(3, 7)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Zone1ExitPointX
+ {
+ get
+ {
+ if (this.LocalZone1ExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone1ExitPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [CsvExportColumn("Zone1ExitPointY", 41)]
+ [Label("Zone 1 exit point (Y-global)")]
+ [Format("F3")]
+ [PropertyOrder(3, 8)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Zone1ExitPointY
+ {
+ get
+ {
+ if (this.LocalZone1ExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone1ExitPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ [CsvExportColumn("Zone1ExitPointZ", 42)]
+ [Label("Zone 1 exit point (Z)")]
+ [Format("F3")]
+ [PropertyOrder(3, 9)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Zone1ExitPointZ
+ {
+ get
+ {
+ if (this.LocalZone1ExitPointX == null)
+ return null;
+ if (redesignedSurfaceLineStability == null)
+ return null;
+ return this.redesignedSurfaceLineStability.Geometry.GetZAtX(this.LocalZone1ExitPointX.Value);
+ }
+ }
+
+ [CsvExportColumn("Zone2SafetyFactorStability", 43)]
+ [Label("Zone 2 safety factor")]
+ [Format("F3")]
+ [PropertyOrder(3, 10)]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ public double? Zone2SafetyFactorStability
+ {
+ get { return this.zone2SafetyFactorStability; }
+ set { this.zone2SafetyFactorStability = value; }
+ }
+
+ [CsvExportColumn("LocalZone2EntryPointX", 44)]
+ [Label("Zone 2 entry point (X-local)")]
+ [Format("F3")]
+ [PropertyOrder(3, 11)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? LocalZone2EntryPointX
+ {
+ get { return localZone2EntryPointX; }
+ set { localZone2EntryPointX = value; }
+ }
+
+ [CsvExportColumn("Zone2EntryPointX", 45)]
+ [Label("Zone 2 entry point (X-global)")]
+ [Format("F3")]
+ [PropertyOrder(3, 12)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Zone2EntryPointX
+ {
+ get
+ {
+ if (this.LocalZone2EntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone2EntryPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+
+ }
+ }
+
+ [CsvExportColumn("Zone2EntryPointY", 46)]
+ [Label("Zone 2 entry point (Y-global)")]
+ [Format("F3")]
+ [PropertyOrder(3, 13)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Zone2EntryPointY
+ {
+ get
+ {
+ if (this.LocalZone2EntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone2EntryPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+
+ }
+ }
+
+ [CsvExportColumn("Zone2EntryPointZ", 47)]
+ [Label("Zone 2 entry point (Z)")]
+ [Format("F3")]
+ [PropertyOrder(3, 14)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Zone2EntryPointZ
+ {
+ get
+ {
+ if (this.LocalZone2EntryPointX == null)
+ return null;
+ if (redesignedSurfaceLineStability == null)
+ return null;
+ return this.redesignedSurfaceLineStability.Geometry.GetZAtX(this.LocalZone2EntryPointX.Value);
+ }
+ }
+
+ [CsvExportColumn("LocalZone2ExitPointX", 48)]
+ [Label("Zone 2 exit point (X-local)")]
+ [Format("F3")]
+ [PropertyOrder(3, 15)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? LocalZone2ExitPointX
+ {
+ get { return localZone2ExitPointX; }
+ set { localZone2ExitPointX = value; }
+ }
+
+ [CsvExportColumn("Zone2ExitPointX", 49)]
+ [Label("Zone 2 exit point (X-global)")]
+ [Format("F3")]
+ [PropertyOrder(3, 16)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Zone2ExitPointX
+ {
+ get
+ {
+ if (this.LocalZone2ExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone2ExitPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [CsvExportColumn("Zone2ExitPointY", 50)]
+ [Label("Zone 2 exit point (Y-global)")]
+ [Format("F3")]
+ [PropertyOrder(3, 17)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Zone2ExitPointY
+ {
+ get
+ {
+ if (this.LocalZone2ExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalZone2ExitPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ [CsvExportColumn("Zone2ExitPointZ", 51)]
+ [Label("Zone 2 exit point (Z)")]
+ [Format("F3")]
+ [PropertyOrder(3, 18)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Zone2ExitPointZ
+ {
+ get
+ {
+ if (this.LocalZone2ExitPointX == null)
+ return null;
+ if (redesignedSurfaceLineStability == null)
+ return null;
+ return this.redesignedSurfaceLineStability.Geometry.GetZAtX(this.LocalZone2ExitPointX.Value);
+ }
+ }
+
+ [CsvExportColumn("IsUplift", 52)]
+ [Label("Uplift")]
+ [PropertyOrder(1, 4)]
+ [ReadOnly(true)]
+ public bool? IsUplift
+ {
+ get { return this.isUplift; }
+ set { this.isUplift = value; }
+ }
+
+ [CsvExportColumn("Pl3MinUplift", 53)]
+ [Label("PL3 Min uplift")]
+ [Format("F3")]
+ [PropertyOrder(5, 1)]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ public double? Pl3MinUplift
+ {
+ get { return this.pl3MinUplift; }
+ set { this.pl3MinUplift = value; }
+ }
+
+ [CsvExportColumn("Pl3HeadAdjusted", 54)]
+ [Label("PL3 Head adjusted")]
+ [Format("F3")]
+ [PropertyOrder(5, 2)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Pl3HeadAdjusted
+ {
+ get { return this.pl3HeadAdjusted; }
+ set { this.pl3HeadAdjusted = value; }
+ }
+
+ [CsvExportColumn("pl3LocalLocationXMinUplift", 55)]
+ [Label("PL3 Min uplift (X-local)")]
+ [Format("F3")]
+ [PropertyOrder(5, 3)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Pl3LocalLocationXMinUplift
+ {
+ get { return this.pl3LocalLocationXMinUplift; }
+ set { this.pl3LocalLocationXMinUplift = value; }
+ }
+
+ [CsvExportColumn("Pl3LocationXMinUplift", 56)]
+ [Label("PL3 Min uplift (X-global)")]
+ [Format("F3")]
+ [PropertyOrder(5, 4)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? Pl3LocationXMinUplift
+ {
+ get
+ {
+ if (this.pl3LocalLocationXMinUplift == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.pl3LocalLocationXMinUplift.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [CsvExportColumn("Pl3LocationYMinUplift", 57)]
+ [Label("PL3 Min uplift (Y-global)")]
+ [Format("F3")]
+ [PropertyOrder(5, 5)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? Pl3LocationYMinUplift
+ {
+ get
+ {
+ if (this.pl3LocalLocationXMinUplift == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.pl3LocalLocationXMinUplift.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ [CsvExportColumn("Pl4MinUplift", 58)]
+ [Label("PL4 Min uplift")]
+ [Format("F3")]
+ [PropertyOrder(5, 6)]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ public double? Pl4MinUplift
+ {
+ get { return this.pl4MinUplift; }
+ set { this.pl4MinUplift = value; }
+ }
+
+ [CsvExportColumn("Pl4HeadAdjusted", 59)]
+ [Label("PL4 Head adjusted")]
+ [Format("F3")]
+ [PropertyOrder(5, 7)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Pl4HeadAdjusted
+ {
+ get { return this.pl4HeadAdjusted; }
+ set { this.pl4HeadAdjusted = value; }
+ }
+
+ [CsvExportColumn("pl4LocalLocationXMinUplift", 60)]
+ [Label("PL4 Min uplift (X-local)")]
+ [Format("F3")]
+ [PropertyOrder(5, 8)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? Pl4LocalLocationXMinUplift
+ {
+ get { return this.pl4LocalLocationXMinUplift; }
+ set { this.pl4LocalLocationXMinUplift = value; }
+ }
+
+ [CsvExportColumn("Pl4LocationXMinUplift", 61)]
+ [Label("PL4 Min uplift (X-global)")]
+ [Format("F3")]
+ [PropertyOrder(5, 9)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? Pl4LocationXMinUplift
+ {
+ get
+ {
+ if (this.pl4LocalLocationXMinUplift == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.pl4LocalLocationXMinUplift.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [CsvExportColumn("Pl4LocationYMinUplift", 62)]
+ [Label("PL4 Min uplift (Y-global)")]
+ [Format("F3")]
+ [PropertyOrder(5, 10)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? Pl4LocationYMinUplift
+ {
+ get
+ {
+ if (this.pl4LocalLocationXMinUplift == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.pl4LocalLocationXMinUplift.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ [Label("Uplift Factor")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ //[Browsable(false)]
+ public double? UpliftFactor
+ {
+ get { return this.upliftFactor; }
+ set { this.upliftFactor = value; }
+ }
+
+ [Label("Heave Factor")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ //[Browsable(false)]
+ public double? HeaveFactor
+ {
+ get { return this.heaveFactor; }
+ set { this.heaveFactor = value; }
+ }
+
+ [CsvExportColumn("BlighPipingFactor", 63)]
+ [Label("Bligh piping factor")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? BlighPipingFactor
+ {
+ get { return this.blighPipingFactor; }
+ set { this.blighPipingFactor = value; }
+ }
+
+ [CsvExportColumn("BlighHCritical", 64)]
+ [Label("Bligh H critical")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? BlighHCritical
+ {
+ get { return this.blighHCritical; }
+ set { this.blighHCritical = value; }
+ }
+
+ [CsvExportColumn("Sellmeijer2ForcesPipingFactor", 65)]
+ [Label("Sellmeijer 2 piping factor")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? Sellmeijer2ForcesPipingFactor
+ {
+ get { return this.sellmeijer2ForcesPipingFactor; }
+ set { this.sellmeijer2ForcesPipingFactor = value; }
+ }
+
+ [CsvExportColumn("Sellmeijer2ForcesHCritical", 66)]
+ [Label("Sellmeijer 2 H Critical")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? Sellmeijer2ForcesHCritical
+ {
+ get { return this.sellmeijer2ForcesHCritical; }
+ set { this.sellmeijer2ForcesHCritical = value; }
+ }
+
+ [CsvExportColumn("Sellmeijer4ForcesPipingFactor", 67)]
+ [Label("Sellmeijer 4 piping factor")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? Sellmeijer4ForcesPipingFactor
+ {
+ get { return this.sellmeijer4ForcesPipingFactor; }
+ set { this.sellmeijer4ForcesPipingFactor = value; }
+ }
+
+ [CsvExportColumn("Sellmeijer4ForcesHCritical", 68)]
+ [Label("Sellmeijer 4 H Critical")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? Sellmeijer4ForcesHCritical
+ {
+ get { return this.sellmeijer4ForcesHCritical; }
+ set { this.sellmeijer4ForcesHCritical = value; }
+ }
+
+ [CsvExportColumn("SellmeijerPipingFactor", 69)]
+ [Label("Sellmeijer piping factor")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? SellmeijerPipingFactor
+ {
+ get { return this.sellmeijerPipingFactor; }
+ set { this.sellmeijerPipingFactor = value; }
+ }
+
+ [CsvExportColumn("SellmeijerHCritical", 70)]
+ [Label("Sellmeijer H Critical")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? SellmeijerHCritical
+ {
+ get { return this.sellmeijerHCritical; }
+ set { this.sellmeijerHCritical = value; }
+ }
+
+ ///
+ /// Gets or sets the wti2017 piping factor.
+ ///
+ ///
+ /// The wti2017 piping factor.
+ ///
+ [Label("WTI 2017 piping factor")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? Wti2017PipingFactor
+ {
+ get { return wti2017PipingFactor; }
+ set { wti2017PipingFactor = value; }
+ }
+
+ ///
+ /// Gets or sets the wti2017 h critical.
+ ///
+ ///
+ /// The wti2017 h critical.
+ ///
+ [Label("WTI 2017 H Critical")]
+ [Format("F3")]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? Wti2017HCritical
+ {
+ get { return wti2017HCritical; }
+ set { wti2017HCritical = value; }
+ }
+
+ [CsvExportColumn("NonWaterRetainingObjectId", 71)]
+ [Browsable(false)]
+ public string NwoId { get { return this.nwoId; } }
+
+ [CsvExportColumn("NWOResultIndex", 72)]
+ [Browsable(false)]
+ public int NwoResultIndex
+ {
+ get { return this.nwoResultIndex; }
+ }
+
+ [CsvExportColumn("NWOPoint1Xrd", 73)]
+ [Browsable(false)]
+ public double? NWOLocationXrdStart
+ {
+ get { return this.locationXrdStart; }
+ }
+
+ [CsvExportColumn("NWOPoint1Yrd", 74)]
+ [Browsable(false)]
+ public double? NWOLocationYrdStart
+ {
+ get { return this.locationYrdStart; }
+ }
+
+ [CsvExportColumn("NWOPoint1Zrd", 75)]
+ [Browsable(false)]
+ public double? NWOLocationZrdStart
+ {
+ get { return this.locationZrdStart; }
+ }
+
+ [CsvExportColumn("NWOPoint4Yrd", 76)]
+ [Browsable(false)]
+ public double? NWOLocationXrdEnd
+ {
+ get { return this.locationXrdEnd; }
+ }
+
+ [CsvExportColumn("NWOPoint4Xrd", 77)]
+ [Browsable(false)]
+ public double? NWOLocationYrdEnd
+ {
+ get { return this.locationYrdEnd; }
+ }
+
+ [CsvExportColumn("NWOPoint4Zrd", 78)]
+ [Browsable(false)]
+ 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!
+
+ [CsvExportColumn("DikeToeAtRiverXrd", 79)]
+ [Browsable(false)]
+ public double? DikeToeAtRiverXrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X; }
+ }
+
+ [CsvExportColumn("DikeToeAtRiverYrd", 80)]
+ [Browsable(false)]
+ public double? DikeToeAtRiverYrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).Y; }
+ }
+
+ [CsvExportColumn("DikeToeAtRiverZrd", 81)]
+ [Browsable(false)]
+ public double? DikeToeAtRiverZrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).Z; }
+ }
+
+ [CsvExportColumn("DikeTopAtRiverXrd", 82)]
+ [Browsable(false)]
+ public double? DikeTopAtRiverXrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X; }
+ }
+
+ [CsvExportColumn("DikeTopAtRiverYrd", 83)]
+ [Browsable(false)]
+ public double? DikeTopAtRiverYrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Y; }
+ }
+
+ [CsvExportColumn("DikeTopAtRiverZrd", 84)]
+ [Browsable(false)]
+ public double? DikeTopAtRiverZrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z; }
+ }
+
+ [CsvExportColumn("DikeTopAtPolderXrd", 85)]
+ [Browsable(false)]
+ public double? DikeTopAtPolderXrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X; }
+ }
+
+ [CsvExportColumn("DikeTopAtPolderYrd", 86)]
+ [Browsable(false)]
+ public double? DikeTopAtPolderYrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Y; }
+ }
+
+ [CsvExportColumn("DikeTopAtPolderZrd", 87)]
+ [Browsable(false)]
+ public double? DikeTopAtPolderZrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z; }
+ }
+
+ [CsvExportColumn("DikeToeAtPolderXrd", 88)]
+ [Browsable(false)]
+ public double? DikeToeAtPolderXrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; }
+ }
+
+ [CsvExportColumn("DikeToeAtPolderYrd", 89)]
+ [Browsable(false)]
+ public double? DikeToeAtPolderYrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Y; }
+ }
+
+ [CsvExportColumn("DikeToeAtPolderZrd", 90)]
+ [Browsable(false)]
+ public double? DikeToeAtPolderZrd
+ {
+ get { return this.Scenario.Location.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; }
+ }
+
+ [CsvExportColumn("FlowSlideSafetyFactor", 91)]
+ [Label("Flowslide safety factor")]
+ [Format("F3")]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [Browsable(false)]
+ public double? FlowSlideSafetyFactor
+ {
+ get { return this.safetyFactorFlowSlide; }
+ set { this.safetyFactorFlowSlide = value; }
+ }
+
+ [Browsable(false)]
+ public Scenario Scenario
+ {
+ get { return scenario; }
+ set { scenario = value; }
+ }
+
+ [Browsable(false)]
+ public SoilProfile1D SoilProfile
+ {
+ get { return soilProfile; }
+ set { soilProfile = value; }
+ }
+
+ [Browsable(false)]
+ public string SoilGeometry2DName
+ {
+ get { return soilGeometry2DName; }
+ set { soilGeometry2DName = value; }
+ }
+
+ ///
+ /// Creates a new instance based on
+ /// with global coordinates instead of local coordinates.
+ ///
+ [Browsable(false)]
+ 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 LocalizedGeometryPointString()
+ };
+ redesignedSurfaceLineStabilityGlobal.Assign(this.RedesignedSurfaceLine2Stability);
+ coordinateSystemConverter.ConvertLocalXZToGlobalXYZ(redesignedSurfaceLineStabilityGlobal.Geometry);
+
+ return redesignedSurfaceLineStabilityGlobal;
+ }
+
+ [Browsable(false)]
+ public SurfaceLine2 RedesignedSurfaceLine2Stability
+ {
+ get { return redesignedSurfaceLineStability; }
+ set { redesignedSurfaceLineStability = value; }
+ }
+
+ ///
+ /// Creates a new instance based on
+ /// with global coordinates instead of local coordinates.
+ ///
+ [Browsable(false)]
+ 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 LocalizedGeometryPointString()
+ };
+ redesignedSurfaceLinePipingGlobal.Assign(this.RedesignedSurfaceLine2Piping);
+ coordinateSystemConverter.ConvertLocalXZToGlobalXYZ(redesignedSurfaceLinePipingGlobal.Geometry);
+
+ return redesignedSurfaceLinePipingGlobal;
+ }
+
+ [Browsable(false)]
+ public SurfaceLine2 RedesignedSurfaceLine2Piping
+ {
+ get { return redesignedSurfaceLinePiping; }
+ set { redesignedSurfaceLinePiping = value; }
+ }
+
+ [Label("Profile")]
+ [PropertyOrder(2, 1)]
+ [XmlIgnore]
+ [ReadOnly(true)]
+ 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;
+ }
+ }
+
+ [Label("Profile probability")]
+ [Format("F3")]
+ [PropertyOrder(2, 2)]
+ [Unit(UnitType.Fractions)]
+ [ReadOnly(true)]
+ [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;
+ }
+ }
+
+ [Label("StabilityModel")]
+ [Unit(UnitType.None)]
+ [PropertyOrder(2, 3)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public MStabModelType? StabilityModel
+ {
+ get
+ {
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityOutside:
+ case FailureMechanismSystemType.StabilityInside:
+ return damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.Model;
+ default:
+ return null;
+ }
+ }
+ }
+
+ [Label("SafetyFactor")]
+ [Unit(UnitType.None)]
+ [Format("F3")]
+ [PropertyOrder(2, 4)]
+ [ReadOnly(true)]
+ [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;
+ }
+ }
+
+ [Label("Failure probability")]
+ [Format("F3")]
+ [PropertyOrder(2, 5)]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [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;
+ }
+ }
+
+ [Label("Required failure probability")]
+ [Format("F3")]
+ [PropertyOrder(2, 9)]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? RequiredFailureProbability
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.Piping:
+ res = RequiredFailureProbabilityPiping;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [Label("Required safety factor")]
+ [Format("F3")]
+ [PropertyOrder(2, 10)]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [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;
+ }
+ }
+
+ [Label("Shoulder height")]
+ [Format("F3")]
+ [PropertyOrder(2, 5)]
+ [Unit(UnitType.Length)]
+ [XmlIgnore]
+ [ReadOnly(true)]
+ public double? ShoulderHeight
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilityShoulderHeight;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingShoulderHeight;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [Label("Toe polder")]
+ [Format("F3")]
+ [PropertyOrder(2, 7)]
+ [Unit(UnitType.Length)]
+ [XmlIgnore]
+ [ReadOnly(true)]
+ public double? ToeAtPolderX
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilityToeAtPolderX;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingToeAtPolderX;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [Label("Height toe polder")]
+ [Format("F3")]
+ [PropertyOrder(2, 8)]
+ [Unit(UnitType.Length)]
+ [XmlIgnore]
+ [ReadOnly(true)]
+ public double? ToeAtPolderZ
+ {
+ get
+ {
+ double? res = null;
+ switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ case FailureMechanismSystemType.StabilityInside:
+ res = StabilityToeAtPolderZ;
+ break;
+ case FailureMechanismSystemType.Piping:
+ res = PipingToeAtPolderZ;
+ break;
+ }
+ return res;
+ }
+ }
+
+ [Label("Piping model")]
+ [PropertyOrder(6, 1)]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public PipingModelType? PipingModel
+ {
+ get
+ {
+ if (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.Piping)
+ {
+ return damFailureMechanismeCalculationSpecification.PipingModelType;
+ }
+ return null;
+ }
+ }
+
+ [Label("Piping factor")]
+ [Format("F3")]
+ [PropertyOrder(6, 2)]
+ [Unit(UnitType.None)]
+ [ReadOnly(true)]
+ [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;
+ }
+ }
+
+ [Label("Piping entry point (X-local)")]
+ [Format("F3")]
+ [PropertyOrder(6, 3)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [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;
+ }
+ }
+
+ [Label("Piping entry point (X-global)")]
+ [Format("F3")]
+ [PropertyOrder(6, 4)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? PipingEntryPointX
+ {
+ get
+ {
+ if (this.LocalPipingEntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalPipingEntryPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [Label("Piping entry point (Y-global)")]
+ [Format("F3")]
+ [PropertyOrder(6, 5)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? PipingEntryPointY
+ {
+ get
+ {
+ if (this.LocalPipingEntryPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalPipingEntryPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ [Label("Piping exit point (X-local)")]
+ [Format("F3")]
+ [PropertyOrder(6, 6)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? LocalPipingExitPointX
+ {
+ get { return localPipingExitPointX; }
+ set { localPipingExitPointX = value; }
+ }
+
+ [Label("Piping exit point (X-global)")]
+ [Format("F3")]
+ [PropertyOrder(6, 7)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? PipingExitPointX
+ {
+ get
+ {
+ if (this.LocalPipingExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalPipingExitPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.X;
+ }
+ }
+
+ [Label("Piping exit point (Y-global)")]
+ [Format("F3")]
+ [PropertyOrder(6, 8)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [XmlIgnore]
+ public double? PipingExitPointY
+ {
+ get
+ {
+ if (this.LocalPipingExitPointX == null)
+ return null;
+
+ GeometryPoint point = DetermineGlobalPointCoordinatesBasedOnGlobalSurfaceLine(
+ new GeometryPoint(this.LocalPipingExitPointX.Value, 0.0, 0.0), this.Scenario.Location.SurfaceLine2);
+
+ return point.Y;
+ }
+ }
+
+ [Format("F3")]
+ [PropertyOrder(6, 9)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ public double? SeepageLength
+ {
+ get { return LocalPipingExitPointX - LocalPipingEntryPointX; }
+ }
+
+ [Label("H critical")]
+ [Format("F3")]
+ [PropertyOrder(6, 10)]
+ [Unit(UnitType.Length)]
+ [ReadOnly(true)]
+ [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;
+ }
+ }
+
+ [Browsable(false)]
+ public string BaseFileName
+ {
+ get { return baseFileName; }
+ set { baseFileName = value; }
+ }
+
+ [Browsable(false)]
+ public string CalculationSubDir
+ {
+ get { return calculationSubDir; }
+ set { calculationSubDir = value; }
+ }
+
+ [Label("Evaluation")]
+ //[Category(ResultCategory)]
+ public ResultEvaluation ResultEvaluation
+ {
+ get { return resultEvaluation; }
+ set
+ {
+ DataEventPublisher.BeforeChange(this, "ResultEvaluation");
+ resultEvaluation = value;
+ DataEventPublisher.AfterChange(this, "ResultEvaluation");
+ }
+ }
+
+ [Label("Notes")]
+ [Description("Use this area to explain the valuation and for any further remarks")]
+ //[Category(ResultCategory)]
+ public string Notes
+ {
+ get { return notes; }
+ set
+ {
+ DataEventPublisher.BeforeChange(this, "Notes");
+ notes = value;
+ DataEventPublisher.AfterChange(this, "Notes");
+ }
+ }
+
+ ///
+ /// Returns the begin point and and 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 GeographicPoint(this.locationXrdStart.Value, this.locationYrdStart.Value));
+ }
+ if (this.locationXrdEnd.HasValue && this.locationYrdEnd.HasValue)
+ {
+ points.Add(new GeographicPoint(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 = StabilityCalculator.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;
+ }
+
+ public bool IsEnabled(string property)
+ {
+ return true;
+ }
+
+ public bool IsVisible(string property)
+ {
+ switch (property)
+ {
+ // #Bka note that using FailureMechanismSystemType here is only possible as long as multiple specifications are NOT allowed. Otherwise visibility would
+ // have top be set here per line instead for whole column.
+ case "Zone1SafetyFactorStability":
+ case "Zone1EntryPointX":
+ case "Zone1EntryPointZ":
+ case "Zone1ExitPointX":
+ case "Zone1ExitPointZ":
+ case "Zone2SafetyFactorStability":
+ case "Zone2EntryPointX":
+ case "Zone2EntryPointZ":
+ case "Zone2ExitPointX":
+ case "Zone2ExitPointZ":
+ return damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside;// &&
+ //(damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.ZonesType == MStabZonesType.ZoneAreas ||
+ //damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.ZonesType == MStabZonesType.ForbiddenZone);
+ //#Bka: zones are defined per location so can differ from result to result. Hence using Isvisible is not possible for this as zones should then be made
+ // visible or invisible per line in the table.
+ case "StabilityModel":
+ return damFailureMechanismeCalculationSpecification.FailureMechanismSystemType ==
+ FailureMechanismSystemType.StabilityInside ||
+ damFailureMechanismeCalculationSpecification.FailureMechanismSystemType ==
+ FailureMechanismSystemType.StabilityOutside;
+ case "RequiredSafetyFactor":
+ return probabilisticType == ProbabilisticType.Deterministic;
+ case "SafetyFactor":
+ return probabilisticType == ProbabilisticType.Deterministic;
+ case "FailureProbability":
+ return probabilisticType == ProbabilisticType.Probabilistic || probabilisticType == ProbabilisticType.ProbabilisticFragility;
+ case "RequiredFailureProbability":
+ return probabilisticType == ProbabilisticType.Probabilistic || probabilisticType == ProbabilisticType.ProbabilisticFragility;
+ case "PipingModel":
+ return damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.Piping;
+ case "PipingFactor":
+ return damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.Piping;
+ case "HCritical":
+ return damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.Piping;
+ case "OpenCalculationFile":
+ return File.Exists(GetCurrentExeForOpenCalculationFile());
+ case "IsUplift":
+ return !(damFailureMechanismeCalculationSpecification.StabilityKernelType == StabilityKernelType.AdvancedWti ||
+ damFailureMechanismeCalculationSpecification.StabilityKernelType == StabilityKernelType.AdvancedDotNet);
+ default:
+ return true;
+ }
+
+ }
+
+ #region Backwards compatibility
+
+ [Obsolete("Do not use this method; Only exists for backwards compatibility purposes.", true)]
+ [XmlIgnore]
+ [Browsable(false)]
+ public SurfaceLine RedesignedSurfaceLineStability
+ {
+ get { return null; }
+ set { redesignedSurfaceLineStability = new OldSurfaceLineToNewConverter().Convert(value);}
+ }
+
+ [Obsolete("Do not use this method; Only exists for backwards compatibility purposes.", true)]
+ [XmlIgnore]
+ [Browsable(false)]
+ public SurfaceLine RedesignedSurfaceLinePiping
+ {
+ get { return null; }
+ set { redesignedSurfaceLinePiping = new OldSurfaceLineToNewConverter().Convert(value); }
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamProjectCalculator.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamProjectCalculator.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DamProjectCalculator.cs (revision 274)
@@ -0,0 +1,960 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2011 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 03-02-2011
+// Toplevel Calculator object which will perform all single calculations
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Xml.Serialization;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Data.Design;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Standard.Calculation;
+using Deltares.DamEngine.Data.Standard.Logging;
+
+namespace Deltares.DamEngine.Calculators
+{
+ public class DamProjectCalculator
+ {
+ private readonly DamProjectData damProjectData;
+ private readonly Object lockObject = new object();
+ private int maxCalculationCores = 255;
+ private string slopeWProgramPath = "";
+ private string mStabProgramPath = "";
+ private string calculationBaseDirectory = "";
+
+ ///
+ /// Constructor
+ ///
+ ///
+ public DamProjectCalculator(DamProjectData damProjectData)
+ {
+ this.damProjectData = damProjectData;
+ }
+
+ ///
+ /// Base directory where the project is stored
+ /// Needed to find the 2d geometries
+ ///
+ public string ProjectDataDirectory { get; set; }
+
+ public ProgressDelegate Progress { get; set; }
+
+ ///
+ /// Properties
+ ///
+ public string CalculationBaseDirectory
+ {
+ get
+ {
+ return calculationBaseDirectory;
+ }
+ set
+ {
+ calculationBaseDirectory = value;
+ }
+ }
+
+ public string MStabProgramPath
+ {
+ get
+ {
+ return mStabProgramPath;
+ }
+ set
+ {
+ mStabProgramPath = value;
+ }
+ }
+
+ public string SlopeWProgramPath
+ {
+ get
+ {
+ return slopeWProgramPath;
+ }
+ set
+ {
+ slopeWProgramPath = value;
+ }
+ }
+
+ public int MaxCalculationCores
+ {
+ get
+ {
+ return maxCalculationCores;
+ }
+ set
+ {
+ maxCalculationCores = value;
+ }
+ }
+
+ ///
+ /// Validate if all parameters are available for calculation of project
+ ///
+ public void ValidateGeneral()
+ {
+ // ToDo make this intelligent depending on the specification
+ ThrowHelper.ThrowWhenConditionIsTrue("No actual calculation specified.",
+ () => damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications.Count == 0);
+ }
+
+ ///
+ /// Validate if all parameters are available for calculation of project
+ ///
+ public void ValidateSpecification()
+ {
+ // ToDo make this intelligent depending on the specification
+ if (damProjectData.ProgramType == ProgramType.MStab)
+ {
+ ThrowHelper.ThrowIfFileNotExist(MStabProgramPath, StringResourceNames.MStabExecutableFileNameNotFound);
+ }
+ if (damProjectData.ProgramType == ProgramType.SlopeW)
+ {
+ ThrowHelper.ThrowIfFileNotExist(SlopeWProgramPath, StringResourceNames.SlopeWExecutableFileNameNotFound);
+ }
+ }
+
+ ///
+ /// Perform the calculations
+ ///
+ public List> Calculate(DamProjectData damProjectData, IList scenarios)
+ {
+ foreach (var scenario in scenarios)
+ {
+ foreach (var dike in damProjectData.WaterBoard.Dikes)
+ {
+ if (dike.Locations.Contains(scenario.Location))
+ {
+ dike.UpdateLocation(scenario.Location);
+ break;
+ }
+ }
+ }
+
+ ValidateGeneral();
+
+ Parallel.Run((IList) scenarios, RunScenario, Progress, MaxCalculationCores);
+
+ var allCalculationResults = scenarios.Select(scenario => scenario.CalculationResults).ToList();
+
+ PostprocessForStabilityUpliftVanBishop(ref allCalculationResults);
+
+ this.damProjectData.UpdateDesignCalculations();
+
+ return allCalculationResults;
+ }
+
+ ///
+ /// Determine where lowest uplift factor occurs and the value of that factor
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public double? GetLowestUpliftFactor(SurfaceLine2 surfaceLine, SoilProfile1D soilProfile, string soilGeometry2DName, PLLines plLines, Location location)
+ {
+ var upliftLocationDeterminator = new UpliftLocationDeterminator()
+ {
+ SurfaceLine = surfaceLine,
+ SoilProfile = soilProfile,
+ SoilGeometry2DName = soilGeometry2DName,
+ SoilBaseDB = location.SoilbaseDB,
+ SoilList = location.SoilList,
+ DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(),
+ PLLines = plLines,
+ XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin
+ };
+ UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationAtWithLowestUpliftFactor();
+ if (upliftLocationAndResult != null)
+ {
+ return upliftLocationAndResult.UpliftFactor;
+ }
+ return null;
+ }
+
+ ///
+ /// Determines whether it is a combined stability bishop and liftvan calculation.
+ ///
+ /// The calculation specification.
+ ///
+ /// true if it is a stability bishop and liftvan calculation; otherwise, false.
+ ///
+ private bool IsStabilityBishopLiftVanCalculation(DamFailureMechanismeCalculationSpecification calculationSpecification)
+ {
+ return ((calculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) &&
+ ((MStabModelType) calculationSpecification.CalculationModel == MStabModelType.BishopUpliftVan));
+ }
+
+ ///
+ /// Calculate one scenario
+ ///
+ ///
+ private void RunScenario(object scenarioTask)
+ {
+ var scenario = (Scenario) scenarioTask;
+ var scenarioName = scenario.Location.Name;
+ Debug.WriteLine(String.Format("Start thread for location '{0}'", scenarioName));
+ DataEventPublisher.InvokeWithoutPublishingEvents(() =>
+ {
+ Location oldLocation = null;
+
+ try
+ {
+ oldLocation = scenario.Location;
+ var scenarioId = scenario.LocationScenarioID;
+ Debug.WriteLine("Location '{0}', scenario '{1}'", scenarioName, scenarioId);
+ scenario.ClearResults();
+ scenario.ClearErrors();
+
+ CloneLocationOnScenario(scenario);
+
+ if (scenario.PlLineOffsetBelowDikeToeAtPolder.HasValue)
+ {
+ scenario.Location.PlLineOffsetBelowDikeToeAtPolder = scenario.PlLineOffsetBelowDikeToeAtPolder.Value;
+ }
+ if (scenario.PlLineOffsetBelowDikeTopAtPolder.HasValue)
+ {
+ scenario.Location.PlLineOffsetBelowDikeTopAtPolder = scenario.PlLineOffsetBelowDikeTopAtPolder.Value;
+ }
+ if (scenario.PlLineOffsetBelowDikeTopAtRiver.HasValue)
+ {
+ scenario.Location.PlLineOffsetBelowDikeTopAtRiver = scenario.PlLineOffsetBelowDikeTopAtRiver.Value;
+ }
+ if (scenario.PlLineOffsetBelowShoulderBaseInside.HasValue)
+ {
+ scenario.Location.PlLineOffsetBelowShoulderBaseInside = scenario.PlLineOffsetBelowShoulderBaseInside.Value;
+ }
+ if (scenario.PlLineOffsetBelowDikeCrestMiddle.HasValue)
+ {
+ scenario.Location.PlLineOffsetBelowDikeCrestMiddle = scenario.PlLineOffsetBelowDikeCrestMiddle;
+ }
+ if (scenario.PlLineOffsetFactorBelowShoulderCrest.HasValue)
+ {
+ scenario.Location.PlLineOffsetFactorBelowShoulderCrest = scenario.PlLineOffsetFactorBelowShoulderCrest;
+ }
+ if (scenario.UsePlLineOffsetBelowDikeCrestMiddle.HasValue)
+ {
+ scenario.Location.UsePlLineOffsetBelowDikeCrestMiddle = scenario.UsePlLineOffsetBelowDikeCrestMiddle;
+ }
+ if (scenario.UsePlLineOffsetFactorBelowShoulderCrest.HasValue)
+ {
+ scenario.Location.UsePlLineOffsetFactorBelowShoulderCrest = scenario.UsePlLineOffsetFactorBelowShoulderCrest;
+ }
+ if (scenario.HeadPl3.HasValue)
+ {
+ scenario.Location.HeadPl3 = scenario.HeadPl3.Value;
+ }
+ if (scenario.HeadPl4.HasValue)
+ {
+ scenario.Location.HeadPl4 = scenario.HeadPl4.Value;
+ }
+
+ var selectedKernelType = StabilityKernelType.DamClassic;
+ var damProjectCalculationSpecification = damProjectData.DamProjectCalculationSpecification;
+ var spec = damProjectCalculationSpecification.DamCalculationSpecifications.First();
+ if (spec != null)
+ {
+ selectedKernelType = spec.StabilityKernelType;
+ }
+ if (DetermineStabilityUpliftForScenarios(scenario, selectedKernelType))
+ {
+
+ // Save the results after each calculation, because these will be deleted in the next calculation
+ var calculationresults = new List();
+
+ foreach (var calculationSpecification in damProjectCalculationSpecification.DamCalculationSpecifications)
+ {
+ var selectedProbabilisticType = damProjectCalculationSpecification.SelectedProbabilisticType;
+ var analysisType = DamProjectCalculationSpecification.SelectedAnalysisType;
+
+ Debug.WriteLine("Location '{0}', scenario '{1}' 10", scenarioName, scenarioId);
+ ValidateSpecification();
+ if (IsStabilityBishopLiftVanCalculation(calculationSpecification))
+ {
+ Debug.WriteLine("Location '{0}', scenario '{1}' 11", scenarioName, scenarioId);
+ CalculateStabilityBishopUpliftvanForScenario(scenario, calculationSpecification, selectedProbabilisticType, analysisType);
+ }
+ else
+ {
+ Debug.WriteLine("Location '{0}', scenario '{1}' 15", scenarioName, scenarioId);
+ CalculateOneCalculationTypeForScenario(scenario, calculationSpecification, selectedProbabilisticType, analysisType);
+ }
+ Debug.WriteLine("Location '{0}', scenario '{1}' 20", scenarioName, scenarioId);
+ calculationresults.AddRange(scenario.CalculationResults);
+ }
+ // Assign the combined results to the scenario
+ scenario.CalculationResults.Clear();
+ scenario.CalculationResults.AddRange(calculationresults);
+ }
+
+ }
+ catch (Exception exception)
+ {
+ scenario.Errors.Add(exception.Message);
+ }
+ finally
+ {
+ if( oldLocation != null)
+ {
+ scenario.Location = oldLocation;
+ }
+ }
+ });
+ }
+
+ private void CloneLocationOnScenario(Scenario scenario)
+ {
+ lock (lockObject)
+ {
+ // TODO missing clone method for Location. This is a dirty way of performing a clone.
+ var locationUsedInCalculation = new XmlSerializer().SerializeToString(scenario.Location);
+ var location = new XmlDeserializer().XmlDeserializeFromString(locationUsedInCalculation);
+ scenario.Location = location;
+ }
+ }
+
+ ///
+ /// Calculates combined stability bishop and upliftvan for scenario.
+ ///
+ /// The scenario.
+ /// The calculation specification.
+ /// Type of the probabilistic.
+ /// Type of the analysis.
+ private void CalculateStabilityBishopUpliftvanForScenario(Scenario scenario, DamFailureMechanismeCalculationSpecification calculationSpecification, ProbabilisticType probabilisticType, AnalysisType analysisType)
+ {
+ var bishopCalculationSpecification = new DamFailureMechanismeCalculationSpecification();
+ bishopCalculationSpecification.Assign(calculationSpecification);
+ bishopCalculationSpecification.CalculationModel = MStabModelType.Bishop;
+ var liftvanCalculationSpecification = new DamFailureMechanismeCalculationSpecification();
+ liftvanCalculationSpecification.Assign(calculationSpecification);
+ liftvanCalculationSpecification.CalculationModel = MStabModelType.UpliftVan;
+ // Make sure check on uplift is performed before doing UpliftVan calculation
+ liftvanCalculationSpecification.FailureMechanismeParamatersMStab.IsStabilityCheckOnUplift = true;
+
+ // First perform calculate Bishop
+ CalculateOneCalculationTypeForScenario(scenario, bishopCalculationSpecification, probabilisticType, analysisType);
+ // Save the results, because these will be deleted in the next calculation
+ var calculationresults = new List();
+ calculationresults.AddRange(scenario.CalculationResults);
+ // Now run LiftVan calculation
+ CalculateOneCalculationTypeForScenario(scenario, liftvanCalculationSpecification, probabilisticType, analysisType);
+ // Combine Bishop and Liftvan results and assign them to the scenario
+ calculationresults.AddRange(scenario.CalculationResults);
+ scenario.CalculationResults.Clear();
+ scenario.CalculationResults.AddRange(calculationresults);
+ }
+
+ ///
+ /// Calculates one calculation type for scenario.
+ ///
+ /// The scenario.
+ /// The dam failure mechanisme calculation specification.
+ /// Type of the probabilistic.
+ /// Type of the analysis.
+ private void CalculateOneCalculationTypeForScenario(
+ Scenario scenario,
+ DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification,
+ ProbabilisticType probabilisticType,
+ AnalysisType analysisType)
+ {
+ if (damProjectData.WaterBoard.Dikes.Count > 1)
+ {
+ throw new Exception("Not possible to calculate with more than one dike");
+ }
+
+ var dike = damProjectData.WaterBoard.Dikes[0];
+ var damProjectCalculatorLogBuilder = new DamProjectCalculatorCsvExportDataBuilder
+ (
+ dike,
+ scenario,
+ damFailureMechanismeCalculationSpecification,
+ analysisType,
+ probabilisticType
+ );
+
+ scenario.ClearResults();
+ scenario.ClearErrors();
+
+ var damFailureMechanismeCalculator = new DamFailureMechanismeCalculator(
+ damProjectData.ProgramType,
+ damFailureMechanismeCalculationSpecification,
+ MStabProgramPath,
+ SlopeWProgramPath,
+ dike.MapForSoilGeometries2D,
+ probabilisticType);
+ damFailureMechanismeCalculator.CalculationBaseDirectory = CalculationBaseDirectory;
+
+ if (analysisType == AnalysisType.AdaptNWO)
+ {
+ damFailureMechanismeCalculator.NonWaterRetainingObject = dike.NonWaterRetainingObjects[0];
+ }
+
+ if (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside ||
+ damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityOutside)
+ {
+ StabilityCalculator.ModelSubDirectory = damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.Model.ToString();
+ }
+
+ try
+ {
+ damFailureMechanismeCalculator.Calculate(analysisType, scenario);
+
+ foreach (var error in scenario.Errors)
+ {
+ var logMessage = new LogMessage(LogMessageType.Error, null, error);
+ damFailureMechanismeCalculator.ErrorMessages.Add(logMessage);
+ }
+ foreach (var errorMessage in damFailureMechanismeCalculator.ErrorMessages)
+ {
+ LogManager.Messages.Add(errorMessage);
+ }
+
+ var recordIndex = 0;
+ var firstNwoSoilProfileProbability = true;
+ var validSoilProfileProbabilities = DamFailureMechanismeCalculator.SelectProbabilitiesForFailureMechanism(
+ damFailureMechanismeCalculationSpecification.FailureMechanismSystemType, scenario.Location.Segment.SoilProfileProbabilities);
+ foreach (var soilProfileProbability in validSoilProfileProbabilities)
+ {
+ if (analysisType == AnalysisType.AdaptNWO)
+ {
+ if (firstNwoSoilProfileProbability)
+ {
+ // for NWO, only add results for every first soilProfileProbability as the others are already part of the nwo results.
+ foreach (var nwoResult in scenario.NwoResults)
+ {
+ var resultMessage = scenario.GetResultMessage(
+ nwoResult.SoilProfileProbability.SoilProfile,
+ nwoResult.SoilProfileProbability.SoilGeometry2DName);
+ // The error message can contain "," and ";" and should therefor be surrounded with double quotes, so it will be read correctly as a scv file
+ damProjectCalculatorLogBuilder.Append(
+ @"""",
+ ++recordIndex,
+ " - ",
+ resultMessage,
+ " - ",
+ nwoResult.NwoId,
+ " - ",
+ nwoResult.LocationXrdStart,
+ " - ",
+ nwoResult.MStabResults.CalculationName,
+ @""""
+ );
+
+ scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(nwoResult.SoilProfileProbability, scenario.NwoResults.IndexOf(nwoResult)));
+ scenario.CalculationResult = CalculationResult.Succeeded;
+ }
+ foreach (var error in scenario.Errors)
+ {
+ damProjectCalculatorLogBuilder.Append(error);
+ scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(soilProfileProbability));
+ scenario.CalculationResult = CalculationResult.Succeeded;
+ }
+ firstNwoSoilProfileProbability = false;
+ }
+ else
+ {
+ if (scenario.CalculationResult != CalculationResult.NoRun)
+ {
+ // The error message can contain "," and ";" and should therefor be surrounded with double quotes, so it will be read correctly as a csv file
+ string resultMessage = scenario.GetResultMessage(soilProfileProbability.SoilProfile,
+ soilProfileProbability.SoilGeometry2DName);
+ damProjectCalculatorLogBuilder.Append(
+ @"""",
+ ++recordIndex,
+ " - ",
+ resultMessage,
+ @""""
+ );
+
+ scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(soilProfileProbability));
+ }
+ scenario.CalculationResult = CalculationResult.Succeeded;
+ }
+ }
+ else
+ {
+ // The error message can contain "," and ";" and should therefor be surrounded with double quotes, so it will be read correctly as a scv file
+ var resultMessage = scenario.GetResultMessage(
+ soilProfileProbability.SoilProfile,
+ soilProfileProbability.SoilGeometry2DName);
+
+ damProjectCalculatorLogBuilder.Append(
+ @"""",
+ ++recordIndex,
+ " - ",
+ resultMessage,
+ @""""
+ );
+
+ scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(soilProfileProbability, damFailureMechanismeCalculationSpecification.StabilityKernelType));
+ scenario.CalculationResult = CalculationResult.Succeeded;
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ damProjectCalculatorLogBuilder.Append("Error: ", exception.Message);
+
+ var innerException = exception.InnerException;
+ while (innerException != null)
+ {
+ damProjectCalculatorLogBuilder.Append(": ", innerException.Message);
+ innerException = innerException.InnerException;
+ }
+
+ foreach (var error in scenario.Errors)
+ {
+ var logMessage = new LogMessage(LogMessageType.Error, null, error);
+ LogManager.Messages.Add(logMessage);
+ }
+ foreach (var errorMessage in damFailureMechanismeCalculator.ErrorMessages)
+ {
+ LogManager.Messages.Add(errorMessage);
+ }
+
+ foreach (var soilProfileProbability in scenario.Location.Segment.SoilProfileProbabilities)
+ {
+ if (soilProfileProbability.SegmentFailureMechanismType == null ||
+ soilProfileProbability.SegmentFailureMechanismType == damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
+ {
+ scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(soilProfileProbability));
+ scenario.CalculationResult = CalculationResult.UnexpectedError;
+ }
+ }
+ throw;
+ }
+ }
+
+ ///
+ /// Determine for each scenario if uplift occurs
+ ///
+ ///
+ ///
+ ///
+ private bool DetermineStabilityUpliftForScenarios(Scenario scenario, StabilityKernelType stabilityKernelType)
+ {
+ if (stabilityKernelType == StabilityKernelType.AdvancedWti ||
+ stabilityKernelType == StabilityKernelType.AdvancedDotNet)
+ {
+ return true;
+ }
+ var res = true;
+ Dike dike = damProjectData.WaterBoard.Dikes[0];
+ double upliftCriterion = scenario.GetUpliftCriterionStability(scenario.Location.ModelFactors.UpliftCriterionStability);
+ foreach (var soilProfileProbability in scenario.Location.Segment.SoilProfileProbabilities)
+ {
+ if (soilProfileProbability.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityInside ||
+ soilProfileProbability.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityOutside ||
+ soilProfileProbability.SegmentFailureMechanismType == null)
+ {
+ try
+ {
+ SurfaceLine2 surfaceLineWithNewHeight = DamFailureMechanismeCalculator.RedesignSurfaceLineHeight(FailureMechanismSystemType.StabilityInside, scenario,
+ scenario.Location.LocalXZSurfaceLine2);
+ // for scenarios the uplift should be calculated with the redesigned height, else a problem may occur with the waterlevel above the dike
+ var upliftSituation = new UpliftSituation();
+ PLLines plLines = CreateAllPLLines(out upliftSituation, scenario.RiverLevel,
+ scenario.RiverLevelLow, scenario.Location, soilProfileProbability,
+ surfaceLineWithNewHeight);
+
+ if (plLines != null)
+ {
+ string fullSoilGeometry2DName = (soilProfileProbability.SoilGeometry2DName == null) ? null :
+ Path.Combine(ProjectDataDirectory, Path.Combine(dike.MapForSoilGeometries2D, soilProfileProbability.SoilGeometry2DName));
+ double? upliftFactor = GetLowestUpliftFactor(surfaceLineWithNewHeight,
+ soilProfileProbability.SoilProfile, fullSoilGeometry2DName, plLines, scenario.Location);
+ upliftSituation.IsUplift = (upliftFactor < upliftCriterion);
+ }
+ else
+ {
+ upliftSituation.IsUplift = false;
+ }
+ scenario.SetStabilityUpliftSituation(soilProfileProbability.SoilProfile,
+ soilProfileProbability.SoilGeometry2DName, upliftSituation);
+ }
+ catch (Exception exception)
+ {
+ string errorMessage = String.Format("{0} in location '{1}' scenario '{2}' soilprofile '{3}'",
+ exception.Message, scenario.Location.Name,
+ scenario.LocationScenarioID,
+ soilProfileProbability.SoilGeometryName);
+ scenario.SetResultMessage(soilProfileProbability.SoilProfile,
+ soilProfileProbability.SoilGeometry2DName, exception.Message);
+ var resultRecord = new CsvExportData(
+ "Error: " + exception.Message,
+ dike,
+ damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications[0],
+ scenario,
+ soilProfileProbability.SoilProfile,
+ soilProfileProbability.SoilGeometry2DName,
+ DamProjectCalculationSpecification.SelectedAnalysisType,
+ 0,
+ damProjectData.DamProjectCalculationSpecification.SelectedProbabilisticType);
+ scenario.CalculationResults.Add(resultRecord);
+ scenario.Errors.Add(errorMessage);
+ scenario.CalculationResult = CalculationResult.RunFailed;
+ res = false;
+ }
+ }
+ }
+ foreach (var error in scenario.Errors)
+ {
+ var logMessage = new LogMessage(LogMessageType.Error, null, error);
+ LogManager.Messages.Add(logMessage);
+ }
+ return res;
+ }
+
+ ///
+ /// Determines whether the specified calculation result is Bishop.
+ ///
+ /// The calculation result.
+ ///
+ /// true if it is Bishop; otherwise, false.
+ ///
+ private bool IsBishopResult(CsvExportData calculationResult)
+ {
+ return ((calculationResult.DamFailureMechanismeCalculation.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) &&
+ (calculationResult.DamFailureMechanismeCalculation.FailureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.Bishop));
+ }
+
+ ///
+ /// Determines whether the specified calculation result is UpliftVan.
+ ///
+ /// The calculation result.
+ ///
+ /// true if it is UpliftVan; otherwise, false.
+ ///
+ private bool IsUpliftVanResult(CsvExportData calculationResult)
+ {
+ return ((calculationResult.DamFailureMechanismeCalculation.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) &&
+ (calculationResult.DamFailureMechanismeCalculation.FailureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.UpliftVan));
+ }
+
+ ///
+ /// Create new results depending on Uplift
+ ///
+ ///
+ private void PostprocessForStabilityUpliftVanBishop(ref List> allCalculationResults)
+ {
+ var normativeCalculationResults = new List();
+ var bishopCalculationResults = new List();
+ var upliftVanCalculationResults = new List();
+
+ // First collect all Bishop and Uplift calculations
+ foreach (var calculationResults in allCalculationResults)
+ {
+ if (calculationResults.Count > 0)
+ {
+ foreach (var calculationResult in calculationResults)
+ {
+ if (IsBishopResult(calculationResult))
+ {
+ bishopCalculationResults.Add(calculationResult);
+ }
+ if (IsUpliftVanResult(calculationResult))
+ {
+ upliftVanCalculationResults.Add(calculationResult);
+ }
+ }
+ }
+ }
+ if ((bishopCalculationResults.Any()) && (upliftVanCalculationResults.Any()))
+ {
+ var bishopLiftvancalculation = bishopCalculationResults[0].DamFailureMechanismeCalculation.Clone();
+ bishopLiftvancalculation.FailureMechanismeParamatersMStab.MStabParameters.Model = MStabModelType.BishopUpliftVan;
+ foreach (var bishopCalculationRecord in bishopCalculationResults)
+ {
+ CsvExportData liftVanCalculationResult = (from calculationResult in upliftVanCalculationResults
+ where calculationResult.LocationName.Equals(bishopCalculationRecord.LocationName) &&
+ calculationResult.ScenarioName.Equals(bishopCalculationRecord.ScenarioName) &&
+ calculationResult.StabilityProfileName.Equals(bishopCalculationRecord.StabilityProfileName)
+ select calculationResult).ToList().FirstOrDefault();
+ CsvExportData normativeCalculationResult = SelectStabilityNormativeResult(bishopCalculationRecord, liftVanCalculationResult,
+ bishopCalculationRecord.AnalysisType, bishopCalculationRecord.ProbabilisticType);
+ // Clone this result, to make sure the original won't be changed
+ normativeCalculationResult = (CsvExportData) normativeCalculationResult.Clone();
+ normativeCalculationResult.DamFailureMechanismeCalculation = bishopLiftvancalculation;
+ normativeCalculationResults.Add(normativeCalculationResult);
+ // Add the normative result also to the scenario
+ normativeCalculationResult.Scenario.CalculationResults.Add(normativeCalculationResult);
+ }
+ allCalculationResults.Add(normativeCalculationResults);
+ }
+ }
+
+ ///
+ /// Select which result is the norm for stability Bishop/UpliftVan calculation
+ ///
+ ///
+ ///
+ ///
+ private CsvExportData SelectStabilityNormativeResult(CsvExportData bishopCalculationRecord, CsvExportData liftVanCalculationResult, AnalysisType analysisType, ProbabilisticType probabilisticType)
+ {
+ switch (analysisType)
+ {
+ case AnalysisType.NoAdaption:
+ switch (probabilisticType)
+ {
+ case ProbabilisticType.Deterministic:
+ return SelectStabilityNormativeResultDeterministicNormal(liftVanCalculationResult, bishopCalculationRecord);
+ case ProbabilisticType.Probabilistic:
+ case ProbabilisticType.ProbabilisticFragility:
+ return SelectStabilityNormativeResultProbabilisticNormal(liftVanCalculationResult, bishopCalculationRecord);
+ default:
+ throw new ArgumentOutOfRangeException("probabilisticType");
+ }
+ case AnalysisType.AdaptNWO:
+ case AnalysisType.AdaptGeometry:
+ switch (probabilisticType)
+ {
+ case ProbabilisticType.Deterministic:
+ return SelectStabilityNormativeResultDeterministicDesign(liftVanCalculationResult, bishopCalculationRecord);
+ case ProbabilisticType.Probabilistic:
+ case ProbabilisticType.ProbabilisticFragility:
+ return SelectStabilityNormativeResultProbabilisticDesign(liftVanCalculationResult, bishopCalculationRecord);
+ default:
+ throw new ArgumentOutOfRangeException("probabilisticType");
+ }
+ default:
+ throw new ArgumentOutOfRangeException("analysisType");
+ }
+ }
+
+ ///
+ /// Select which result is the norm for stability Bishop/UpliftVan normal deterministic calculation
+ ///
+ ///
+ ///
+ ///
+ private CsvExportData SelectStabilityNormativeResultDeterministicNormal(CsvExportData liftVanCalculationResult, CsvExportData bishopCalculationRecord)
+ {
+ if ((liftVanCalculationResult != null) && (liftVanCalculationResult.StabilitySafetyFactor.HasValue))
+ {
+ if ((bishopCalculationRecord != null) && (bishopCalculationRecord.StabilitySafetyFactor.HasValue))
+ {
+ return (liftVanCalculationResult.StabilitySafetyFactor.Value < bishopCalculationRecord.StabilitySafetyFactor.Value
+ ? liftVanCalculationResult
+ : bishopCalculationRecord);
+ }
+ else
+ {
+ return liftVanCalculationResult;
+ }
+ }
+ else
+ {
+ return bishopCalculationRecord;
+ }
+ }
+
+ ///
+ /// Select which result is the norm for stability Bishop/UpliftVan design probabilistic calculation
+ ///
+ ///
+ ///
+ ///
+ private CsvExportData SelectStabilityNormativeResultProbabilisticDesign(CsvExportData liftVanCalculationResult, CsvExportData bishopCalculationRecord)
+ {
+ throw new ApplicationException("Not implemented yet");
+ }
+
+ ///
+ /// Select which result is the norm for stability Bishop/UpliftVan design deterministic calculation
+ ///
+ ///
+ ///
+ ///
+ private CsvExportData SelectStabilityNormativeResultDeterministicDesign(CsvExportData liftVanCalculationResult, CsvExportData bishopCalculationRecord)
+ {
+ if ((liftVanCalculationResult != null) && (liftVanCalculationResult.StabilitySafetyFactor.HasValue))
+ {
+ if ((bishopCalculationRecord != null) && (bishopCalculationRecord.StabilitySafetyFactor.HasValue))
+ {
+ bool dla = liftVanCalculationResult.DikeLength.HasValue;
+ dla = dla && bishopCalculationRecord.DikeLength.HasValue;
+ if (dla && (Math.Abs(liftVanCalculationResult.DikeLength.Value - bishopCalculationRecord.DikeLength.Value) < GeometryPoint.Precision))
+ {
+ return (liftVanCalculationResult.StabilitySafetyFactor <
+ bishopCalculationRecord.StabilitySafetyFactor
+ ? liftVanCalculationResult
+ : bishopCalculationRecord);
+ }
+ else
+ {
+ return (liftVanCalculationResult.DikeLength > bishopCalculationRecord.DikeLength
+ ? liftVanCalculationResult
+ : bishopCalculationRecord);
+ }
+ }
+ else
+ {
+ return liftVanCalculationResult;
+ }
+ }
+ else
+ {
+ return bishopCalculationRecord;
+ }
+ }
+
+ ///
+ /// Select which result is the norm for stability Bishop/UpliftVan normal probabilistic calculation
+ ///
+ ///
+ ///
+ ///
+ private CsvExportData SelectStabilityNormativeResultProbabilisticNormal(CsvExportData liftVanCalculationResult, CsvExportData bishopCalculationRecord)
+ {
+ throw new ApplicationException("Not implemented yet");
+ }
+
+ ///
+ /// Create PLLines with selected model
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// the created pl lines
+ private PLLines CreateAllPLLines(out UpliftSituation upliftSituation, double waterLevel, double? waterLevelLow, Location location, SoilGeometryProbability soilProfileProbability, SurfaceLine2 surfaceLine)
+ {
+ switch (location.PLLineCreationMethod)
+ {
+ case PLLineCreationMethod.ExpertKnowledgeLinearInDike:
+ case PLLineCreationMethod.ExpertKnowledgeRRD:
+ case PLLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD:
+ return CreateAllPLLinesExpertKnowledge(out upliftSituation, waterLevel, waterLevelLow, location, soilProfileProbability, surfaceLine);
+ case PLLineCreationMethod.DupuitStatic:
+ string geometryDirectory = DamProject.ProjectWorkingPath;
+ return CreateAllPLLinesDupuit(out upliftSituation, location, soilProfileProbability, surfaceLine, geometryDirectory, waterLevel);
+ case PLLineCreationMethod.DupuitDynamic:
+ throw new DamCalculationException("PL-Line creation with DupuitDynamic not yet implemented");
+ default:
+ upliftSituation.Pl3HeadAdjusted = 0;
+ upliftSituation.Pl3LocationXMinUplift = 0;
+ upliftSituation.Pl3MinUplift = 0;
+ upliftSituation.Pl4HeadAdjusted = 0;
+ upliftSituation.Pl4LocationXMinUplift = 0;
+ upliftSituation.Pl4MinUplift = 0;
+ upliftSituation.IsUplift = false; // must be determined later on; just to avoid compiler error
+ return null;
+ }
+ }
+
+ ///
+ /// Create PLLines with Dupuit model
+ ///
+ /// the created pl lines
+ private PLLines CreateAllPLLinesDupuit(out UpliftSituation upliftSituation, Location location, SoilGeometryProbability soilProfileProbability,
+ SurfaceLine2 surfaceLine, String geometryDirectory, double waterLevel)
+ {
+ var timeSerieIn = new TimeSerie();
+ timeSerieIn.Entries.Add(new TimeSerieEntry(DateTime.Now, waterLevel));
+ var plLinesCreatorDupuit = new PLLinesCreatorDupuit
+ {
+ Geometry2DData = Geometry2DDataCreator.CreateGeometry2DData(location, soilProfileProbability, surfaceLine, geometryDirectory),
+ SurfaceLine = location.LocalXZSurfaceLine2,
+ WaterLevelTimeserie = timeSerieIn,
+ SoilList = location.SoilList,
+ PolderLevel = location.PolderLevel,
+ IsReverseLayerOrder = true
+ };
+
+ upliftSituation.Pl3HeadAdjusted = 0;
+ upliftSituation.Pl3LocationXMinUplift = 0;
+ upliftSituation.Pl3MinUplift = 0;
+ upliftSituation.Pl4HeadAdjusted = 0;
+ upliftSituation.Pl4LocationXMinUplift = 0;
+ upliftSituation.Pl4MinUplift = 0;
+ upliftSituation.IsUplift = false; // must be determined later on; just to avoid compiler error
+ plLinesCreatorDupuit.CreateAllPlLines();
+
+ return null;
+ }
+
+ ///
+ /// Create PLLines with expert knowledge
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// the created pl lines
+ private PLLines CreateAllPLLinesExpertKnowledge(out UpliftSituation upliftSituation, double waterLevel,
+ double? waterLevelLow, Location location, SoilGeometryProbability soilProfileProbability,
+ SurfaceLine2 surfaceLine)
+ {
+ var plLinesCreator = new PLLinesCreator();
+ // Determine geometry type
+ SoilGeometryType soilGeometryType = soilProfileProbability.SoilGeometryType;
+ string mapForSoilGeometries2D = location.MapForSoilGeometries2D;
+ SoilProfile1D soilProfile = soilProfileProbability.SoilProfile;
+ string soilGeometry2DName = soilProfileProbability.SoilGeometry2DName;
+ if ((soilProfileProbability.SoilGeometry2DName != null) && (mapForSoilGeometries2D != null))
+ {
+ soilGeometry2DName = Path.Combine(mapForSoilGeometries2D, soilGeometry2DName);
+ soilGeometry2DName = Path.Combine(ProjectDataDirectory, soilGeometry2DName);
+ }
+
+ plLinesCreator.WaterLevelRiverHigh = waterLevel;
+ plLinesCreator.WaterLevelRiverLow = waterLevelLow;
+ plLinesCreator.IsUseLowWaterLevel = (damProjectData.DamProjectCalculationSpecification.CurrentSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityOutside);
+
+ plLinesCreator.SurfaceLine = surfaceLine;
+ plLinesCreator.WaterLevelPolder = location.PolderLevel;
+ plLinesCreator.HeadInPLLine2 = location.HeadPL2;
+ plLinesCreator.HeadInPLLine3 = location.HeadPl3;
+ plLinesCreator.HeadInPLLine4 = location.HeadPl4;
+ plLinesCreator.ModelParametersForPLLines = location.CreateModelParametersForPLLines();
+ plLinesCreator.SoilProfile = soilProfile;
+ plLinesCreator.SoilGeometry2DName = soilGeometry2DName;
+ plLinesCreator.SoilGeometryType = soilGeometryType;
+ plLinesCreator.GaugePLLines = location.GaugePLLines;
+ plLinesCreator.Gauges = location.Gauges;
+ plLinesCreator.GaugeMissVal = location.GaugeMissVal;
+ plLinesCreator.IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true; // for stability this must set to true
+ plLinesCreator.SoilBaseDB = location.SoilbaseDB;
+ plLinesCreator.SoilList = location.SoilList;
+ plLinesCreator.DikeEmbankmentMaterial = location.SoilList.GetSoilByName(location.DikeEmbankmentMaterial);
+ plLinesCreator.PlLineOffsetBelowDikeTopAtRiver = location.PlLineOffsetBelowDikeTopAtRiver;
+ plLinesCreator.PlLineOffsetBelowDikeTopAtPolder = location.PlLineOffsetBelowDikeTopAtPolder;
+ plLinesCreator.PlLineOffsetBelowShoulderBaseInside = location.PlLineOffsetBelowShoulderBaseInside;
+ plLinesCreator.PlLineOffsetBelowDikeToeAtPolder = location.PlLineOffsetBelowDikeToeAtPolder;
+ plLinesCreator.PlLineOffsetBelowDikeCrestMiddle = location.PlLineOffsetBelowDikeCrestMiddle;
+ plLinesCreator.PlLineOffsetFactorBelowShoulderCrest = location.PlLineOffsetFactorBelowShoulderCrest;
+ plLinesCreator.UsePlLineOffsetBelowDikeCrestMiddle = location.UsePlLineOffsetBelowDikeCrestMiddle;
+ plLinesCreator.UsePlLineOffsetFactorBelowShoulderCrest = location.UsePlLineOffsetFactorBelowShoulderCrest;
+ plLinesCreator.XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin;
+
+ PLLines plLines = plLinesCreator.CreateAllPLLines(location);
+ upliftSituation.Pl3HeadAdjusted = plLinesCreator.Pl3HeadAdjusted;
+ upliftSituation.Pl3LocationXMinUplift = plLinesCreator.Pl3LocationXMinUplift;
+ upliftSituation.Pl3MinUplift = plLinesCreator.Pl3MinUplift;
+ upliftSituation.Pl4HeadAdjusted = plLinesCreator.Pl4HeadAdjusted;
+ upliftSituation.Pl4LocationXMinUplift = plLinesCreator.Pl4LocationXMinUplift;
+ upliftSituation.Pl4MinUplift = plLinesCreator.Pl4MinUplift;
+ upliftSituation.IsUplift = false; // must be determined later on; just to avoid compiler error
+ return plLines;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamJob.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamJob.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/DamJob.cs (revision 274)
@@ -0,0 +1,41 @@
+using System.ComponentModel;
+
+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/branches/Initial Source/Deltares.DamEngine.Data/General/WaterBoardJob.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/WaterBoardJob.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/WaterBoardJob.cs (revision 274)
@@ -0,0 +1,35 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2009 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 16-2-2011
+// n.a.
+//-----------------------------------------------------------------------
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class WaterBoardJob : CompositeJob
+ {
+ public WaterBoardJob()
+ {
+ }
+ public WaterBoardJob(object subject): base(subject)
+ {
+ }
+
+ public bool AreAllDikeLocationsWaterLevelTimeSeriesAssigned()
+ {
+ bool areAssigned = true;
+ foreach (DamJob damJob in Jobs)
+ {
+ if (damJob.GetType() == typeof(DikeJob))
+ {
+ areAssigned = areAssigned && (((DikeJob)damJob).AreAllLocationWaterLevelTimeSeriesAssigned());
+ }
+ }
+ return areAssigned;
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs (revision 274)
@@ -0,0 +1,157 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/WaterpressureInterpolationModel.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/WaterpressureInterpolationModel.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/WaterpressureInterpolationModel.cs (revision 274)
@@ -0,0 +1,41 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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/branches/Initial Source/Deltares.DamEngine.Data/Standard/DelegatedList.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/DelegatedList.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/DelegatedList.cs (revision 274)
@@ -0,0 +1,142 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard
+{
+
+ ///
+ /// Delegate void SingleArgumentDelegate
+ ///
+ ///
+ /// The argument.
+ public delegate void SingleArgumentDelegate(T argument) where T : class;
+
+ ///
+ /// Extends the standard List<T> class with delegates which are called on adding or removing items
+ ///
+ /// The generic type to create the list for
+ public class DelegatedList : VirtualList where T : class
+ {
+ private SingleArgumentDelegate addMethod;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DelegatedList() {}
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The add method.
+ public DelegatedList(SingleArgumentDelegate addMethod)
+ {
+ AddMethod = addMethod;
+ }
+
+ ///
+ /// Sets the add method.
+ ///
+ ///
+ /// The add method.
+ ///
+ public SingleArgumentDelegate AddMethod
+ {
+ set
+ {
+ addMethod = value;
+ }
+ }
+
+ private void InvokeAddMethod(T newItem)
+ {
+ if (addMethod != null)
+ {
+ addMethod(newItem);
+ }
+ }
+
+ #region List Overrides
+
+ ///
+ /// Gets or sets the element at the specified index.
+ ///
+ /// The index.
+ ///
+ public override T this[int index]
+ {
+ get
+ {
+ return base[index];
+ }
+ set
+ {
+ T newItem = value;
+ base[index] = newItem;
+ InvokeAddMethod(newItem);
+ }
+ }
+
+ ///
+ /// Adds the specified item.
+ ///
+ /// The item.
+ public override void Add(T item)
+ {
+ base.Add(item);
+ InvokeAddMethod(item);
+ }
+
+ ///
+ /// Clears this instance.
+ ///
+ public override void Clear()
+ {
+ foreach (var itemToRemove in ToArray())
+ {
+ Remove(itemToRemove);
+ }
+ }
+
+ ///
+ /// Removes the specified item.
+ ///
+ /// The item.
+ ///
+ public override bool Remove(T item)
+ {
+ bool removed = base.Remove(item);
+ return removed;
+ }
+
+ ///
+ /// Inserts the specified index.
+ ///
+ /// The index.
+ /// The item.
+ public override void Insert(int index, T item)
+ {
+ base.Insert(index, item);
+ InvokeAddMethod(item);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/EvaluationJob.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/EvaluationJob.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/RWScenarios/EvaluationJob.cs (revision 274)
@@ -0,0 +1,133 @@
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using Deltares.Dam.Data;
+using Deltares.DamEngine.Data.General;
+using XmlSerializer = Deltares.Standard.IO.Xml.XmlSerializer;
+
+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