// 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";
}