// Copyright (C) Stichting Deltares 2025. All rights reserved. // // This file is part of the application DAM - UI. // // DAM - UI 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. using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Globalization; using System.Linq.Expressions; using Deltares.DamEngine.Data.Standard; using Deltares.Geotechnics.Soils; using Deltares.Geotechnics.SurfaceLines; using Deltares.Standard; using Deltares.Standard.Attributes; using Deltares.Standard.EventPublisher; using Deltares.Standard.Language; using Deltares.Standard.Units; using Deltares.Standard.Validation; namespace Deltares.Dam.Data; /// /// Does uplift occur or not /// public struct UpliftSituation { public bool IsUplift; public double Pl3MinUplift; public double Pl3HeadAdjusted; public double Pl3LocationXMinUplift; public double Pl4MinUplift; public double Pl4HeadAdjusted; public double Pl4LocationXMinUplift; } [Serializable] public class ScenarioException : Exception { public ScenarioException(string message) : base(message) {} } /// /// Calculation scenario class /// public class Scenario : IVisibleEnabled, IRepairer { private Dictionary stabilityUpliftSituations; private Dictionary pipingResults; private Dictionary safetyFactorsPiping; private Dictionary redesignedSurfaceLines; private Dictionary resultMessages; private string locationScenarioId; private double? riverLevel; private double? riverLevelLow; private double? dikeTableHeight; private double plLineOffsetBelowDikeTopAtRiver = 0.5; private double plLineOffsetBelowDikeTopAtPolder = 1.5; private double plLineOffsetBelowShoulderBaseInside = 0.1; private double plLineOffsetBelowDikeToeAtPolder = 0.1; private bool? usePlLineOffsetBelowDikeCrestMiddle; private double? plLineOffsetBelowDikeCrestMiddle; private bool? usePlLineOffsetFactorBelowShoulderCrest; private double? plLineOffsetFactorBelowShoulderCrest; private double? headPl2; private double? headPl3; private double? headPl4; private double polderLevel; /// /// Constructor /// public Scenario() { ClearResults(); ClearErrors(); ClearstabilityUpliftSituations(); ModelFactors = new ModelFactors(); } [Browsable(false)] public CalculationResult CalculationResult { get; set; } = CalculationResult.NoRun; [Browsable(false)] public List CalculationResults { get; } = new List(); /// /// Gets or sets the location scenario identifier. /// /// /// The location scenario identifier. /// [Browsable(true)] [PropertyOrder(0, 1)] [ReadOnly(true)] public string LocationScenarioID { get { return locationScenarioId; } set { DataEventPublisher.BeforeChange(this, ExpressionLocationScenarioId); locationScenarioId = value; DataEventPublisher.AfterChange(this, ExpressionLocationScenarioId); } } [Browsable(false)] public StringCollection Errors { get; private set; } /// /// Gets or sets the river level. /// /// /// The river level. /// [PropertyOrder(1, 1)] [Unit(UnitType.Length)] [Format("F2")] [Label("River level")] [Description("River level")] public double? RiverLevel { get { return riverLevel; } set { DataEventPublisher.BeforeChange(this, ExpressionRiverLevel); riverLevel = value; DataEventPublisher.AfterChange(this, ExpressionRiverLevel); } } /// /// Gets or sets the river level low. /// /// /// The river level low. /// [PropertyOrder(1, 2)] [Unit(UnitType.Length)] [Format("F2")] [Label("River level low")] [Description("River level low")] public double? RiverLevelLow { get { return riverLevelLow; } set { DataEventPublisher.BeforeChange(this, ExpressionRiverLevelLow); riverLevelLow = value; DataEventPublisher.AfterChange(this, ExpressionRiverLevelLow); } } /// /// Gets or sets the height of the dike table. /// /// /// The height of the dike table. /// [PropertyOrder(1, 3)] [Unit(UnitType.Length)] [Format("F2")] [Label("Dike table height")] [Description("Dike table height")] public double? DikeTableHeight { get { return dikeTableHeight; } set { DataEventPublisher.BeforeChange(this, ExpressionDikeTableHeight); dikeTableHeight = value; DataEventPublisher.AfterChange(this, ExpressionDikeTableHeight); } } /// /// Gets or sets the polder level. /// /// /// The polder level. /// [PropertyOrder(1, 4)] [Unit(UnitType.Length)] [Format("F2")] public double PolderLevel { get { return polderLevel; } set { DataEventPublisher.BeforeChange(this, ExpressionPolderLevel); polderLevel = value; DataEventPublisher.AfterChange(this, ExpressionPolderLevel); } } /// /// Gets or sets the uplift criterion piping. /// /// /// The uplift criterion piping. /// [PropertyOrder(1, 5)] [Unit(UnitType.None)] [Format("F2")] [Label("Uplift criterion piping")] [Description("Uplift criterion piping")] public double UpliftCriterionPiping { get { return ModelFactors.UpliftCriterionPiping; } set { DataEventPublisher.BeforeChange(this, ExpressionUpliftCriterionPiping); ModelFactors.UpliftCriterionPiping = value; DataEventPublisher.AfterChange(this, ExpressionUpliftCriterionPiping); } } /// /// Gets or sets the uplift criterion stability. /// /// /// The uplift criterion stability. /// [PropertyOrder(1, 6)] [Unit(UnitType.None)] [Format("F2")] [Label("Uplift criterion stability")] [Description("Uplift criterion stability")] public double UpliftCriterionStability { get { return ModelFactors.UpliftCriterionStability; } set { DataEventPublisher.BeforeChange(this, ExpressionUpliftCriterionStability); ModelFactors.UpliftCriterionStability = value; DataEventPublisher.AfterChange(this, ExpressionUpliftCriterionStability); } } /// /// Gets or sets the pl line offset below dike top at river side. /// /// /// The pl line offset below dike top at river side. /// [PropertyOrder(1, 7)] [Unit(UnitType.Length)] [Format("F2")] public double PlLineOffsetBelowDikeTopAtRiver { get { return plLineOffsetBelowDikeTopAtRiver; } set { DataEventPublisher.BeforeChange(this, ExpressionPlLineOffsetBelowDikeTopAtRiver); plLineOffsetBelowDikeTopAtRiver = value; DataEventPublisher.AfterChange(this, ExpressionPlLineOffsetBelowDikeTopAtRiver); } } /// /// Gets or sets the pl line offset below dike top at polder. /// /// /// The pl line offset below dike top at polder. /// [PropertyOrder(1, 8)] [Unit(UnitType.Length)] [Format("F2")] public double PlLineOffsetBelowDikeTopAtPolder { get { return plLineOffsetBelowDikeTopAtPolder; } set { DataEventPublisher.BeforeChange(this, ExpressionPlLineOffsetBelowDikeTopAtPolder); plLineOffsetBelowDikeTopAtPolder = value; DataEventPublisher.AfterChange(this, ExpressionPlLineOffsetBelowDikeTopAtPolder); } } /// /// Gets or sets the pl line offset below shoulder base inside. /// /// /// The pl line offset below shoulder base inside. /// [PropertyOrder(1, 9)] [Unit(UnitType.Length)] [Format("F2")] public double PlLineOffsetBelowShoulderBaseInside { get { return plLineOffsetBelowShoulderBaseInside; } set { DataEventPublisher.BeforeChange(this, ExpressionPlLineOffsetBelowShoulderBaseInside); plLineOffsetBelowShoulderBaseInside = value; DataEventPublisher.AfterChange(this, ExpressionPlLineOffsetBelowShoulderBaseInside); } } /// /// Gets or sets the pl line offset below dike toe at polder. /// /// /// The pl line offset below dike toe at polder. /// [PropertyOrder(1, 10)] [Unit(UnitType.Length)] [Format("F2")] public double PlLineOffsetBelowDikeToeAtPolder { get { return plLineOffsetBelowDikeToeAtPolder; } set { DataEventPublisher.BeforeChange(this, ExpressionPlLineOffsetBelowDikeToeAtPolder); plLineOffsetBelowDikeToeAtPolder = value; DataEventPublisher.AfterChange(this, ExpressionPlLineOffsetBelowDikeToeAtPolder); } } /// /// Gets or sets the use pl line offset below dike crest middle. /// /// /// The use pl line offset below dike crest middle. /// [PropertyOrder(1, 11)] [Clearable] public bool? UsePlLineOffsetBelowDikeCrestMiddle { get { return usePlLineOffsetBelowDikeCrestMiddle; } set { DataEventPublisher.BeforeChange(this, ExpressionUsePlLineOffsetBelowDikeCrestMiddle); usePlLineOffsetBelowDikeCrestMiddle = value; DataEventPublisher.AfterChange(this, ExpressionUsePlLineOffsetBelowDikeCrestMiddle); } } /// /// Gets or sets the pl line offset below dike crest middle. /// /// /// The pl line offset below dike crest middle. /// [PropertyOrder(1, 12)] [Unit(UnitType.Length)] [Format("F2")] public double? PlLineOffsetBelowDikeCrestMiddle { get { return plLineOffsetBelowDikeCrestMiddle; } set { DataEventPublisher.BeforeChange(this, ExpressionPlLineOffsetBelowDikeCrestMiddle); plLineOffsetBelowDikeCrestMiddle = value; DataEventPublisher.AfterChange(this, ExpressionPlLineOffsetBelowDikeCrestMiddle); } } /// /// Gets or sets the use pl line offset factor below shoulder crest. /// /// /// The use pl line offset factor below shoulder crest. /// [PropertyOrder(1, 13)] [Clearable] public bool? UsePlLineOffsetFactorBelowShoulderCrest { get { return usePlLineOffsetFactorBelowShoulderCrest; } set { DataEventPublisher.BeforeChange(this, ExpressionUsePlLineOffsetFactorBelowShoulderCrest); usePlLineOffsetFactorBelowShoulderCrest = value; DataEventPublisher.AfterChange(this, ExpressionUsePlLineOffsetFactorBelowShoulderCrest); } } /// /// Gets or sets the pl line offset factor below shoulder crest. /// /// /// The pl line offset factor below shoulder crest. /// [PropertyOrder(1, 14)] [Unit(UnitType.Fractions)] [Format("F2")] public double? PlLineOffsetFactorBelowShoulderCrest { get { return plLineOffsetFactorBelowShoulderCrest; } set { DataEventPublisher.BeforeChange(this, ExpressionPlLineOffsetFactorBelowShoulderCrest); plLineOffsetFactorBelowShoulderCrest = value; DataEventPublisher.AfterChange(this, ExpressionPlLineOffsetFactorBelowShoulderCrest); } } /// /// Gets or sets the head PL2. /// /// /// The head PL2. /// [PropertyOrder(1, 15)] [Unit(UnitType.Length)] [Format("F2")] public double? HeadPl2 { get { return headPl2; } set { DataEventPublisher.BeforeChange(this, ExpressionHeadPl2); headPl2 = value; DataEventPublisher.AfterChange(this, ExpressionHeadPl2); } } /// /// Gets or sets the head PL3. /// /// /// The head PL3. /// [PropertyOrder(1, 16)] [Unit(UnitType.Length)] [Format("F2")] public double? HeadPl3 { get { return headPl3; } set { DataEventPublisher.BeforeChange(this, ExpressionHeadPl3); headPl3 = value; DataEventPublisher.AfterChange(this, ExpressionHeadPl3); } } /// /// Gets or sets the head PL4. /// /// /// The head PL4. /// [PropertyOrder(1, 17)] [Unit(UnitType.Length)] [Format("F2")] public double? HeadPl4 { get { return headPl4; } set { DataEventPublisher.BeforeChange(this, ExpressionHeadPl4); headPl4 = value; DataEventPublisher.AfterChange(this, ExpressionHeadPl4); } } /// /// Gets or sets the required safety factor stability inner slope. /// /// /// The required safety factor stability inner slope. /// [PropertyOrder(1, 18)] [Unit(UnitType.None)] [Format("F2")] public double RequiredSafetyFactorStabilityInnerSlope { get { return ModelFactors.RequiredSafetyFactorStabilityInnerSlope; } set { DataEventPublisher.BeforeChange(this, ExpressionRequiredSafetyFactorStabilityInnerSlope); ModelFactors.RequiredSafetyFactorStabilityInnerSlope = value; DataEventPublisher.AfterChange(this, ExpressionRequiredSafetyFactorStabilityInnerSlope); } } /// /// Gets or sets the required safety factor stability outer slope. /// /// /// The required safety factor stability outer slope. /// [PropertyOrder(1, 19)] [Unit(UnitType.None)] [Format("F2")] public double RequiredSafetyFactorStabilityOuterSlope { get { return ModelFactors.RequiredSafetyFactorStabilityOuterSlope; } set { DataEventPublisher.BeforeChange(this, ExpressionRequiredSafetyFactorStabilityOuterSlope); ModelFactors.RequiredSafetyFactorStabilityOuterSlope = value; DataEventPublisher.AfterChange(this, ExpressionRequiredSafetyFactorStabilityOuterSlope); } } /// /// Gets or sets the required safety factor piping. /// /// /// The required safety factor piping. /// [PropertyOrder(1, 20)] [Unit(UnitType.None)] [Format("F2")] public double RequiredSafetyFactorPiping { get { return ModelFactors.RequiredSafetyFactorPiping; } set { DataEventPublisher.BeforeChange(this, ExpressionRequiredSafetyFactorPiping); ModelFactors.RequiredSafetyFactorPiping = value; DataEventPublisher.AfterChange(this, ExpressionRequiredSafetyFactorPiping); } } [Browsable(false)] public ModelFactors ModelFactors { get; set; } /// Aggregation relationship. [Browsable(false)] public Location Location { get; set; } = null; /// /// Clears the results /// public void ClearstabilityUpliftSituations() { stabilityUpliftSituations = new Dictionary(); } /// /// Clears the errors. /// public void ClearErrors() { Errors = new StringCollection(); } /// /// Clears the results /// public void ClearResults() { CalculationResult = CalculationResult.NoRun; pipingResults = new Dictionary(); safetyFactorsPiping = new Dictionary(); resultMessages = new Dictionary(); redesignedSurfaceLines = new Dictionary(); CalculationResults.Clear(); } /// /// Get uplift criterion for this scenario; return default value if not available /// /// default value if not available /// uplift criterion for this scenario public double GetUpliftCriterionStability(double? defaultUpliftCriterionStability) { if ((defaultUpliftCriterionStability == null) && ModelFactors.UpliftCriterionStability.IsNearEqual(0)) { throw new ScenarioException(String.Format(LocalizationManager.GetTranslatedText(this, "NoUpliftCriterionForStability"), Location.Name, ToString())); } return (ModelFactors.UpliftCriterionStability.IsNearEqual(0) ? defaultUpliftCriterionStability.Value : ModelFactors.UpliftCriterionStability); } /// /// Get uplift criterion for this scenario; return default value if not available /// /// default value if not available /// uplift criterion for this scenario public double GetUpliftCriterionPiping(double? defaultUpliftCriterionPiping) { if ((defaultUpliftCriterionPiping == null) && (ModelFactors.UpliftCriterionPiping.IsNearEqual(0))) { throw new ScenarioException(String.Format(LocalizationManager.GetTranslatedText(this, "NoUpliftCriterionForPiping"), Location.Name, ToString())); } return (ModelFactors.UpliftCriterionPiping.IsNearEqual(0) ? defaultUpliftCriterionPiping.Value : ModelFactors.UpliftCriterionPiping); } /// /// Get required safety factor for this scenario; return default value if not available /// /// default value if not available /// uplift criterion for this scenario public double GetRequiredSafetyFactorPiping(double? defaultRequiredSafetyFactorPiping) { if ((defaultRequiredSafetyFactorPiping == null) && (ModelFactors.RequiredSafetyFactorPiping.IsNearEqual(0))) { throw new ScenarioException(String.Format(LocalizationManager.GetTranslatedText(this, "NoRequiredSafetyFactorPiping"), Location.Name, ToString())); } return (ModelFactors.RequiredSafetyFactorPiping.IsNearEqual(0) ? defaultRequiredSafetyFactorPiping.Value : ModelFactors.RequiredSafetyFactorPiping); } /// /// Determines whether [is pl line offset factor below shoulder crest valid]. /// /// [Validate] public ValidationResult[] IsPlLineOffsetFactorBelowShoulderCrestValid() { if (UsePlLineOffsetFactorBelowShoulderCrest.HasValue && UsePlLineOffsetFactorBelowShoulderCrest.Value && PlLineOffsetFactorBelowShoulderCrest.HasValue) { if (PlLineOffsetFactorBelowShoulderCrest.Value < DamGlobalConstants.PlLineOffsetFactorBelowShoulderCrestMinValue) { return new[] { new ValidationResult(ValidationResultType.Error, LocalizationManager.GetTranslatedText(this, "PlLineOffsetFactorBelowShoulderCrestTooSmall"), this, "PlLineOffsetFactorBelowShoulderCrest", "AssignMinValue", this) }; } if (PlLineOffsetFactorBelowShoulderCrest.Value > DamGlobalConstants.PlLineOffsetFactorBelowShoulderCrestMaxValue) { return new[] { new ValidationResult(ValidationResultType.Error, LocalizationManager.GetTranslatedText(this, "PlLineOffsetFactorBelowShoulderCrestTooLarge"), this, "PlLineOffsetFactorBelowShoulderCrest", "AssignMaxValue", this) }; } } return new ValidationResult[0]; } /// /// Get stability uplift situation /// /// /// /// public UpliftSituation? GetStabilityUpliftSituation(SoilProfile1D soilProfile, string soilGeometry2DName) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); return GetStabilityUpliftSituation(objectAsKey); } /// /// Set stability uplift situation /// /// /// /// public void SetStabilityUpliftSituation(SoilProfile1D soilProfile, string soilGeometry2DName, UpliftSituation upliftSituation) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); SetStabilityUpliftSituation(objectAsKey, upliftSituation); } /// /// Get PipingResults /// /// /// /// public PipingResults? GetPipingResults(SoilProfile1D soilProfile, string soilGeometry2DName) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); return GetPipingResults(objectAsKey); } /// /// Set PipingResults /// /// /// /// public void SetPipingResults(SoilProfile1D soilProfile, string soilGeometry2DName, PipingResults? pipingResults) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); SetPipingResults(objectAsKey, pipingResults); } /// /// Get Safety Factor Piping /// /// /// /// public double? GetSafetyFactorPiping(SoilProfile1D soilProfile, string soilGeometry2DName) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); return GetSafetyFactorPiping(objectAsKey); } /// /// Get Result Message /// /// /// /// public string GetResultMessage(SoilProfile1D soilProfile, string soilGeometry2DName) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); return GetResultMessage(objectAsKey); } /// /// Set Result Message /// /// /// /// public void SetResultMessage(SoilProfile1D soilProfile, string soilGeometry2DName, string resultMessage) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); SetResultMessage(objectAsKey, resultMessage); } /// /// Get Redesigned surfaceline /// /// /// /// public SurfaceLine2 GetRedesignedSurfaceLine(SoilProfile1D soilProfile, string soilGeometry2DName) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); return GetRedesignedSurfaceLine(objectAsKey); } /// /// Set Redesigned surfaceline /// /// /// /// public void SetRedesignedSurfaceLine(SoilProfile1D soilProfile, string soilGeometry2DName, SurfaceLine2 surfaceLine) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); SetRedesignedSurfaceLine(objectAsKey, surfaceLine); } /// /// Get Most recent surfaceline /// /// /// /// public SurfaceLine2 GetMostRecentSurfaceLine(SoilProfile soilProfile, string soilGeometry2DName) { var profile1D = soilProfile as SoilProfile1D; Object objectAsKey = GetObjectAsKey(profile1D, soilGeometry2DName); return GetMostRecentSurfaceLine(objectAsKey); } public Dictionary GetParametersAsNameValuePairs() { var numberFormatInfo = new NumberFormatInfo(); numberFormatInfo.NumberDecimalSeparator = "."; var nameValuePairs = new Dictionary(); nameValuePairs.Add(ScenarioParameterNames.LocationScenarioId, LocationScenarioID); if (RiverLevel != null) { nameValuePairs.Add(ScenarioParameterNames.RiverLevel, RiverLevel.Value.ToString(numberFormatInfo)); } if (RiverLevelLow != null) { nameValuePairs.Add(ScenarioParameterNames.RiverLevelLow, RiverLevelLow.Value.ToString(numberFormatInfo)); } if (DikeTableHeight != null) { nameValuePairs.Add(ScenarioParameterNames.DikeTableHeight, DikeTableHeight.Value.ToString(numberFormatInfo)); } if (ModelFactors != null) { nameValuePairs.Add(ScenarioParameterNames.RequiredSafetyFactorStabilityInnerSlope, ModelFactors.RequiredSafetyFactorStabilityInnerSlope.ToString(numberFormatInfo)); nameValuePairs.Add(ScenarioParameterNames.RequiredSafetyFactorStabilityOuterSlope, ModelFactors.RequiredSafetyFactorStabilityOuterSlope.ToString(numberFormatInfo)); nameValuePairs.Add(ScenarioParameterNames.RequiredSafetyFactorPiping, ModelFactors.RequiredSafetyFactorPiping.ToString(numberFormatInfo)); nameValuePairs.Add(ScenarioParameterNames.UpliftCriterionPiping, ModelFactors.UpliftCriterionPiping.ToString(numberFormatInfo)); nameValuePairs.Add(ScenarioParameterNames.UpliftCriterionStability, ModelFactors.UpliftCriterionStability.ToString(numberFormatInfo)); } nameValuePairs.Add(ScenarioParameterNames.PlLineOffsetBelowDikeTopAtRiver, PlLineOffsetBelowDikeTopAtRiver.ToString(numberFormatInfo)); nameValuePairs.Add(ScenarioParameterNames.PlLineOffsetBelowDikeTopAtPolder, PlLineOffsetBelowDikeTopAtPolder.ToString(numberFormatInfo)); nameValuePairs.Add(ScenarioParameterNames.PlLineOffsetBelowShoulderBaseInside, PlLineOffsetBelowShoulderBaseInside.ToString(numberFormatInfo)); nameValuePairs.Add(ScenarioParameterNames.PlLineOffsetBelowDikeToeAtPolder, PlLineOffsetBelowDikeToeAtPolder.ToString(numberFormatInfo)); if (PlLineOffsetBelowDikeCrestMiddle != null) { nameValuePairs.Add(ScenarioParameterNames.PlLineOffsetBelowDikeCrestMiddle, PlLineOffsetBelowDikeCrestMiddle.Value.ToString(numberFormatInfo)); } if (PlLineOffsetFactorBelowShoulderCrest != null) { nameValuePairs.Add(ScenarioParameterNames.PlLineOffsetFactorBelowShoulderCrest, PlLineOffsetFactorBelowShoulderCrest.Value.ToString(numberFormatInfo)); } if (UsePlLineOffsetBelowDikeCrestMiddle != null) { nameValuePairs.Add(ScenarioParameterNames.UsePlLineOffsetBelowDikeCrestMiddle, UsePlLineOffsetBelowDikeCrestMiddle.Value.ToString()); } if (UsePlLineOffsetFactorBelowShoulderCrest != null) { nameValuePairs.Add(ScenarioParameterNames.UsePlLineOffsetFactorBelowShoulderCrest, UsePlLineOffsetFactorBelowShoulderCrest.Value.ToString()); } if (HeadPl3 != null) { nameValuePairs.Add(ScenarioParameterNames.HeadPl3, HeadPl3.Value.ToString(numberFormatInfo)); } if (HeadPl4 != null) { nameValuePairs.Add(ScenarioParameterNames.HeadPl4, HeadPl4.Value.ToString(numberFormatInfo)); } nameValuePairs.Add(ScenarioParameterNames.PolderLevel, PolderLevel.ToString(numberFormatInfo)); if (HeadPl2 != null) { nameValuePairs.Add(ScenarioParameterNames.HeadPl2, HeadPl2.Value.ToString(numberFormatInfo)); } return nameValuePairs; } public void SetParameterFromNameValuePair(string parameterName, string parameterValue) { var numberFormatInfo = new NumberFormatInfo(); numberFormatInfo.NumberDecimalSeparator = "."; if (parameterName.Equals(ScenarioParameterNames.LocationScenarioId)) { LocationScenarioID = parameterValue; } if (parameterName.Equals(ScenarioParameterNames.RiverLevel)) { RiverLevel = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.RiverLevelLow)) { RiverLevelLow = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.DikeTableHeight)) { DikeTableHeight = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.RequiredSafetyFactorStabilityInnerSlope)) { ModelFactors.RequiredSafetyFactorStabilityInnerSlope = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.RequiredSafetyFactorStabilityOuterSlope)) { ModelFactors.RequiredSafetyFactorStabilityOuterSlope = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.RequiredSafetyFactorPiping)) { ModelFactors.RequiredSafetyFactorPiping = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.UpliftCriterionPiping)) { ModelFactors.UpliftCriterionPiping = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.UpliftCriterionStability)) { ModelFactors.UpliftCriterionStability = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.PlLineOffsetBelowDikeTopAtRiver)) { PlLineOffsetBelowDikeTopAtRiver = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.PlLineOffsetBelowDikeTopAtPolder)) { PlLineOffsetBelowDikeTopAtPolder = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.PlLineOffsetBelowShoulderBaseInside)) { PlLineOffsetBelowShoulderBaseInside = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.PlLineOffsetBelowDikeToeAtPolder)) { PlLineOffsetBelowDikeToeAtPolder = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.PlLineOffsetBelowDikeCrestMiddle)) { PlLineOffsetBelowDikeCrestMiddle = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.PlLineOffsetFactorBelowShoulderCrest)) { PlLineOffsetFactorBelowShoulderCrest = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.UsePlLineOffsetBelowDikeCrestMiddle)) { UsePlLineOffsetBelowDikeCrestMiddle = Convert.ToBoolean(parameterValue); } if (parameterName.Equals(ScenarioParameterNames.UsePlLineOffsetFactorBelowShoulderCrest)) { UsePlLineOffsetFactorBelowShoulderCrest = Convert.ToBoolean(parameterValue); } if (parameterName.Equals(ScenarioParameterNames.HeadPl3)) { HeadPl3 = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.HeadPl4)) { HeadPl4 = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.PolderLevel)) { PolderLevel = Convert.ToDouble(parameterValue, numberFormatInfo); } if (parameterName.Equals(ScenarioParameterNames.HeadPl2)) { HeadPl2 = Convert.ToDouble(parameterValue, numberFormatInfo); } } /// /// Implementation of ToString /// /// public override string ToString() { return $"Location={Location.Name}, " + $"ID={LocationScenarioID} " + $"RiverLevel={RiverLevel} " + $"RiverLevelLow={(RiverLevelLow.HasValue ? RiverLevelLow.Value.ToString(CultureInfo.InvariantCulture) : "?")} " + $"DikeTableHeight={(DikeTableHeight.HasValue ? DikeTableHeight.Value.ToString(CultureInfo.InvariantCulture) : "?")} " + $"RequiredSafetyFactorStabilityInnerSlope={ModelFactors.RequiredSafetyFactorStabilityInnerSlope.ToString(CultureInfo.InvariantCulture)} " + $"RequiredSafetyFactorStabilityOuterSlope={ModelFactors.RequiredSafetyFactorStabilityOuterSlope.ToString(CultureInfo.InvariantCulture)} " + $"PlLineOffsetBelowDikeTopAtRiver={PlLineOffsetBelowDikeTopAtRiver.ToString(CultureInfo.InvariantCulture)} " + $"PlLineOffsetBelowDikeToeAtPolder={PlLineOffsetBelowDikeToeAtPolder.ToString(CultureInfo.InvariantCulture)} " + $"PlLineOffsetBelowDikeTopAtPolder={PlLineOffsetBelowDikeTopAtPolder.ToString(CultureInfo.InvariantCulture)} " + $"PlLineOffsetBelowShoulderBaseInside={PlLineOffsetBelowShoulderBaseInside.ToString(CultureInfo.InvariantCulture)} " + $"UsePlLineOffsetBelowDikeCrestMiddle {(UsePlLineOffsetBelowDikeCrestMiddle.HasValue ? UsePlLineOffsetBelowDikeCrestMiddle.Value.ToString(CultureInfo.InvariantCulture) : "?")} " + $"PlLineOffsetBelowDikeCrestMiddle {(PlLineOffsetBelowDikeCrestMiddle.HasValue ? PlLineOffsetBelowDikeCrestMiddle.Value.ToString(CultureInfo.InvariantCulture) : "?")} " + $"UsePlLineOffsetFactorBelowShoulderCrest {(UsePlLineOffsetFactorBelowShoulderCrest.HasValue ? UsePlLineOffsetFactorBelowShoulderCrest.Value.ToString(CultureInfo.InvariantCulture) : "?")} " + $"PlLineOffsetFactorBelowShoulderCrest {(PlLineOffsetFactorBelowShoulderCrest.HasValue ? PlLineOffsetFactorBelowShoulderCrest.Value.ToString(CultureInfo.InvariantCulture) : "?")} " + $"HeadPl3={(HeadPl3.HasValue ? HeadPl3.Value.ToString(CultureInfo.InvariantCulture) : "?")} " + $"HeadPl4={(HeadPl4.HasValue ? HeadPl4.Value.ToString(CultureInfo.InvariantCulture) : "?")} " + $"PolderLevel={PolderLevel.ToString(CultureInfo.InvariantCulture)} " + $"HeadPl2={(HeadPl2.HasValue ? HeadPl2.Value.ToString(CultureInfo.InvariantCulture) : "?")}"; } /// /// Repairs the specified subject. /// /// The subject. /// The property. /// The identifier. public void Repair(object subject, string property, string id) { if (subject is Scenario) { if (id == "AssignMinValue" && property == "PlLineOffsetFactorBelowShoulderCrest") { PlLineOffsetFactorBelowShoulderCrest = DamGlobalConstants.PlLineOffsetFactorBelowShoulderCrestMinValue; } if (id == "AssignMaxValue" && property == "PlLineOffsetFactorBelowShoulderCrest") { PlLineOffsetFactorBelowShoulderCrest = DamGlobalConstants.PlLineOffsetFactorBelowShoulderCrestMaxValue; } } } /// /// Gets the repair description. /// /// The subject. /// The property. /// The identifier. /// public string GetRepairDescription(object subject, string property, string id) { if (id == "AssignMinValue") { return LocalizationManager.GetTranslatedText(this, "AssignMinValue"); } if (id == "AssignMaxValue") { return LocalizationManager.GetTranslatedText(this, "AssignMaxValue"); } return ""; } public bool IsVisible(string property) { switch (property) { default: return true; } } public bool IsEnabled(string property) { return true; } /// /// Get stability uplift situation /// /// /// private UpliftSituation? GetStabilityUpliftSituation(Object objectAsKey) { return objectAsKey != null && stabilityUpliftSituations.ContainsKey(objectAsKey) ? stabilityUpliftSituations[objectAsKey] : null; } /// /// Set stability uplift situation /// /// /// private void SetStabilityUpliftSituation(Object objectAsKey, UpliftSituation upliftSituation) { stabilityUpliftSituations[objectAsKey] = upliftSituation; } /// /// Get PipingResults /// /// /// private PipingResults? GetPipingResults(Object objectAsKey) { if (objectAsKey != null) { return pipingResults.ContainsKey(objectAsKey) ? pipingResults[objectAsKey] : null; } return null; } /// /// Set PipingResults /// /// /// private void SetPipingResults(Object objectAsKey, PipingResults? pipingResults) { this.pipingResults[objectAsKey] = pipingResults; } /// /// Get Safety Factor Piping /// /// /// private double? GetSafetyFactorPiping(Object objectAsKey) { if (objectAsKey != null) { return safetyFactorsPiping.ContainsKey(objectAsKey) ? safetyFactorsPiping[objectAsKey] : null; } return null; } /// /// Get Result Message /// /// /// private string GetResultMessage(Object objectAsKey) { if (objectAsKey != null) { return resultMessages.ContainsKey(objectAsKey) ? resultMessages[objectAsKey] : null; } return null; } /// /// Set Result Message /// /// /// private void SetResultMessage(Object objectAsKey, string resultMessage) { resultMessages[objectAsKey] = resultMessage; } /// /// Get Redesigned surfaceline /// /// /// private SurfaceLine2 GetRedesignedSurfaceLine(Object objectAsKey) { if (objectAsKey != null) { return redesignedSurfaceLines.ContainsKey(objectAsKey) ? redesignedSurfaceLines[objectAsKey] : null; } return null; } /// /// Set Redesigned surfaceline /// /// /// private void SetRedesignedSurfaceLine(Object objectAsKey, SurfaceLine2 surfaceLine) { redesignedSurfaceLines[objectAsKey] = surfaceLine; } /// /// Get Most recent surfaceline /// /// /// private SurfaceLine2 GetMostRecentSurfaceLine(Object objectAsKey) { if (objectAsKey != null) { return redesignedSurfaceLines.ContainsKey(objectAsKey) ? redesignedSurfaceLines[objectAsKey] ?? Location.LocalXZSurfaceLine2 : Location.LocalXZSurfaceLine2; } return null; } /// /// Determine object key based on either 1d-soilprofile or 2d-geometry /// /// /// /// /// private Object GetObjectAsKey(SoilProfile1D soilProfile, string soilGeometry2DName) { if (soilProfile != null) { return soilProfile; } return soilGeometry2DName; } #region Performance optimization: Extract expression so it only has to be generated once. private static readonly Expression> ExpressionLocationScenarioId = x => x.LocationScenarioID; private static readonly Expression> ExpressionRiverLevel = x => x.RiverLevel; private static readonly Expression> ExpressionRiverLevelLow = x => x.RiverLevelLow; private static readonly Expression> ExpressionDikeTableHeight = x => x.DikeTableHeight; private static readonly Expression> ExpressionRequiredSafetyFactorStabilityInnerSlope = x => x.RequiredSafetyFactorStabilityInnerSlope; private static readonly Expression> ExpressionRequiredSafetyFactorStabilityOuterSlope = x => x.RequiredSafetyFactorStabilityOuterSlope; private static readonly Expression> ExpressionRequiredSafetyFactorPiping = x => x.RequiredSafetyFactorPiping; private static readonly Expression> ExpressionUpliftCriterionPiping = x => x.UpliftCriterionPiping; private static readonly Expression> ExpressionUpliftCriterionStability = x => x.UpliftCriterionStability; private static readonly Expression> ExpressionPlLineOffsetBelowDikeTopAtRiver = x => x.PlLineOffsetBelowDikeTopAtRiver; private static readonly Expression> ExpressionPlLineOffsetBelowDikeTopAtPolder = x => x.PlLineOffsetBelowDikeTopAtPolder; private static readonly Expression> ExpressionPlLineOffsetBelowShoulderBaseInside = x => x.PlLineOffsetBelowShoulderBaseInside; private static readonly Expression> ExpressionPlLineOffsetBelowDikeToeAtPolder = x => x.PlLineOffsetBelowDikeToeAtPolder; private static readonly Expression> ExpressionUsePlLineOffsetBelowDikeCrestMiddle = x => x.UsePlLineOffsetBelowDikeCrestMiddle; private static readonly Expression> ExpressionPlLineOffsetBelowDikeCrestMiddle = x => x.PlLineOffsetBelowDikeCrestMiddle; private static readonly Expression> ExpressionUsePlLineOffsetFactorBelowShoulderCrest = x => x.UsePlLineOffsetFactorBelowShoulderCrest; private static readonly Expression> ExpressionPlLineOffsetFactorBelowShoulderCrest = x => x.PlLineOffsetFactorBelowShoulderCrest; private static readonly Expression> ExpressionHeadPl3 = x => x.HeadPl3; private static readonly Expression> ExpressionHeadPl4 = x => x.HeadPl4; private static readonly Expression> ExpressionPolderLevel = x => x.PolderLevel; private static readonly Expression> ExpressionHeadPl2 = x => x.HeadPl2; #endregion } public static class ScenarioParameterNames { public const string LocationScenarioId = "LocationScenarioId"; public const string RiverLevel = "RiverLevel"; public const string RiverLevelLow = "RiverLevelLow"; public const string DikeTableHeight = "DikeTableHeight"; public const string RequiredSafetyFactorStabilityInnerSlope = "RequiredSafetyFactorStabilityInnerSlope"; public const string RequiredSafetyFactorStabilityOuterSlope = "RequiredSafetyFactorStabilityOuterSlope"; public const string RequiredSafetyFactorPiping = "RequiredSafetyFactorPiping"; public const string UpliftCriterionPiping = "UpliftCriterionPiping"; public const string UpliftCriterionStability = "UpliftCriterionStability"; public const string PlLineOffsetBelowDikeTopAtRiver = "PlLineOffsetBelowDikeTopAtRiver"; public const string PlLineOffsetBelowDikeTopAtPolder = "PlLineOffsetBelowDikeTopAtPolder"; public const string PlLineOffsetBelowShoulderBaseInside = "PlLineOffsetBelowShoulderBaseInside"; public const string PlLineOffsetBelowDikeToeAtPolder = "PlLineOffsetBelowDikeToeAtPolder"; public const string PlLineOffsetBelowDikeCrestMiddle = "PlLineOffsetBelowDikeCrestMiddle"; public const string PlLineOffsetFactorBelowShoulderCrest = "PlLineOffsetFactorBelowShoulderCrest"; public const string UsePlLineOffsetBelowDikeCrestMiddle = "UsePlLineOffsetBelowDikeCrestMiddle"; public const string UsePlLineOffsetFactorBelowShoulderCrest = "UsePlLineOffsetFactorBelowShoulderCrest"; public const string HeadPl3 = "HeadPL3"; public const string HeadPl4 = "HeadPL4"; public const string PolderLevel = "PolderLevel"; public const string HeadPl2 = "HeadPL2"; }