// Copyright (C) Stichting Deltares 2019. All rights reserved. // // This file is part of the Dam Engine. // // The Dam Engine is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Language; using Deltares.DamEngine.Data.Standard.Validation; namespace Deltares.DamEngine.Data.Design { /// /// Calculation scenario class /// public class DesignScenario { private CalculationResult calculationResult = CalculationResult.NoRun; private Location location; private Dictionary redesignedSurfaceLines; private Dictionary resultMessages; private string locationScenarioId; private double riverLevel; private double? riverLevelLow; private double? dikeTableHeight; private double? plLineOffsetBelowDikeTopAtRiver; private double? plLineOffsetBelowDikeTopAtPolder; private double? plLineOffsetBelowShoulderBaseInside; private double? plLineOffsetBelowDikeToeAtPolder; private bool? usePlLineOffsetBelowDikeCrestMiddle; private double? plLineOffsetBelowDikeCrestMiddle; private bool? usePlLineOffsetFactorBelowShoulderCrest; private double? plLineOffsetFactorBelowShoulderCrest; private double? headPl3; private double? headPl4; private double? waterHeightDecimeringsHoogte; private double? maxWaterLevel; public CalculationResult CalculationResult { get { return calculationResult; } set { calculationResult = value; } } /// /// Constructor /// public DesignScenario() { ClearResults(); ClearErrors(); ModelFactors = new ModelFactors(); } /// /// Clears the errors. /// public void ClearErrors() { Errors = new StringCollection(); } /// /// Clears the results /// public void ClearResults() { calculationResult = CalculationResult.NoRun; resultMessages = new Dictionary(); redesignedSurfaceLines = new Dictionary(); } /// /// Gets or sets the location scenario identifier. /// /// /// The location scenario identifier. /// public string LocationScenarioID { get { return locationScenarioId; } set { locationScenarioId = value; } } [Browsable(false)] public StringCollection Errors { get; private set; } /// /// Gets or sets the river level. /// /// /// The river level. /// [Description("River level")] public double RiverLevel { get { return riverLevel; } set { riverLevel = value; } } /// /// Gets or sets the river level low. /// /// /// The river level low. /// [Description("River level low")] public double? RiverLevelLow { get { return riverLevelLow; } set { riverLevelLow = value; } } /// /// Gets or sets the height of the dike table. /// /// /// The height of the dike table. /// [Description("Dike table height")] public double? DikeTableHeight { get { return dikeTableHeight; } set { dikeTableHeight = value; } } /// /// Gets or sets the required safety factor stability inner slope. /// /// /// The required safety factor stability inner slope. /// [Description("Required safety factor stability inner slope")] public double? RequiredSafetyFactorStabilityInnerSlope { get { return ModelFactors.RequiredSafetyFactorStabilityInnerSlope; } set { ModelFactors.RequiredSafetyFactorStabilityInnerSlope = value; } } /// /// Gets or sets the required safety factor stability outer slope. /// /// /// The required safety factor stability outer slope. /// [Description("Required safety factor stability outer slope")] public double? RequiredSafetyFactorStabilityOuterSlope { get { return ModelFactors.RequiredSafetyFactorStabilityOuterSlope; } set { ModelFactors.RequiredSafetyFactorStabilityOuterSlope = value; } } /// /// Gets or sets the required safety factor piping. /// /// /// The required safety factor piping. /// [Description("Required safety factor piping")] public double? RequiredSafetyFactorPiping { get { return ModelFactors.RequiredSafetyFactorPiping; } set { ModelFactors.RequiredSafetyFactorPiping = value; } } /// /// Gets or sets the uplift criterion piping. /// /// /// The uplift criterion piping. /// [Description("Uplift criterion piping")] public double? UpliftCriterionPiping { get { return ModelFactors.UpliftCriterionPiping; } set { ModelFactors.UpliftCriterionPiping = value; } } /// /// Gets or sets the uplift criterion stability. /// /// /// The uplift criterion stability. /// [Description("Uplift criterion stability")] public double? UpliftCriterionStability { get { return ModelFactors.UpliftCriterionStability; } set { ModelFactors.UpliftCriterionStability = value; } } public double? PlLineOffsetBelowDikeTopAtRiver { get { return plLineOffsetBelowDikeTopAtRiver; } set { plLineOffsetBelowDikeTopAtRiver = value; } } /// /// Gets or sets the pl line offset below dike top at polder. /// /// /// The pl line offset below dike top at polder. /// public double? PlLineOffsetBelowDikeTopAtPolder { get { return plLineOffsetBelowDikeTopAtPolder; } set { plLineOffsetBelowDikeTopAtPolder = value; } } /// /// Gets or sets the pl line offset below shoulder base inside. /// /// /// The pl line offset below shoulder base inside. /// public double? PlLineOffsetBelowShoulderBaseInside { get { return plLineOffsetBelowShoulderBaseInside; } set { plLineOffsetBelowShoulderBaseInside = value; } } /// /// Gets or sets the pl line offset below dike toe at polder. /// /// /// The pl line offset below dike toe at polder. /// public double? PlLineOffsetBelowDikeToeAtPolder { get { return plLineOffsetBelowDikeToeAtPolder; } set { plLineOffsetBelowDikeToeAtPolder = value; } } /// /// Gets or sets the use pl line offset below dike crest middle. /// /// /// The use pl line offset below dike crest middle. /// public bool? UsePlLineOffsetBelowDikeCrestMiddle { get { return usePlLineOffsetBelowDikeCrestMiddle; } set { usePlLineOffsetBelowDikeCrestMiddle = value; } } /// /// Gets or sets the pl line offset below dike crest middle. /// /// /// The pl line offset below dike crest middle. /// public double? PlLineOffsetBelowDikeCrestMiddle { get { return plLineOffsetBelowDikeCrestMiddle; } set { plLineOffsetBelowDikeCrestMiddle = value; } } /// /// Gets or sets the use pl line offset factor below shoulder crest. /// /// /// The use pl line offset factor below shoulder crest. /// public bool? UsePlLineOffsetFactorBelowShoulderCrest { get { return usePlLineOffsetFactorBelowShoulderCrest; } set { usePlLineOffsetFactorBelowShoulderCrest = value; } } /// /// Gets or sets the pl line offset factor below shoulder crest. /// /// /// The pl line offset factor below shoulder crest. /// public double? PlLineOffsetFactorBelowShoulderCrest { get { return plLineOffsetFactorBelowShoulderCrest; } set { plLineOffsetFactorBelowShoulderCrest = value; } } /// /// Gets or sets the head PL3. /// /// /// The head PL3. /// public double? HeadPl3 { get { return headPl3; } set { headPl3 = value; } } /// /// Gets or sets the head PL4. /// /// /// The head PL4. /// public double? HeadPl4 { get { return headPl4; } set { headPl4 = value; } } /// /// Gets or sets the water height decimerings hoogte. /// /// /// The water height decimerings hoogte. /// public double? WaterHeightDecimeringsHoogte { get { return waterHeightDecimeringsHoogte; } set { waterHeightDecimeringsHoogte = value; } } /// /// Gets or sets the maximum water level. /// /// /// The maximum water level. /// public double? MaxWaterLevel { get { return maxWaterLevel; } set { maxWaterLevel = value; } } /// /// Gets or sets the model factors. /// /// /// The model factors. /// public ModelFactors ModelFactors { get; set; } /// Aggregation relationship. public Location Location { get { return location; } set { location = value; } } /// /// 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) }; } if (PlLineOffsetFactorBelowShoulderCrest.Value > DamGlobalConstants.PlLineOffsetFactorBelowShoulderCrestMaxValue) { return new[] { new ValidationResult(ValidationResultType.Error, LocalizationManager.GetTranslatedText(this, "PlLineOffsetFactorBelowShoulderCrestTooLarge"), this) }; } } return new ValidationResult[0]; } /// /// Get Result Message /// /// /// private string GetResultMessage(Object objectAsKey) { if (objectAsKey != null) { return resultMessages.ContainsKey(objectAsKey) ? resultMessages[objectAsKey] : null; } return null; } /// /// Get Result Message /// /// /// /// public string GetResultMessage(SoilProfile1D soilProfile, string soilGeometry2DName) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); return GetResultMessage(objectAsKey); } /// /// Set Result Message /// /// /// private void SetResultMessage(Object objectAsKey, string resultMessage) { resultMessages[objectAsKey] = resultMessage; } /// /// Set Result Message /// /// /// /// public void SetResultMessage(SoilProfile1D soilProfile, string soilGeometry2DName, string resultMessage) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); SetResultMessage(objectAsKey, resultMessage); } /// /// Set Redesigned surfaceline /// /// /// private void SetRedesignedSurfaceLine(Object objectAsKey, SurfaceLine2 surfaceLine) { redesignedSurfaceLines[objectAsKey] = surfaceLine; } /// /// Set Redesigned surfaceline /// /// /// /// public void SetRedesignedSurfaceLine(SoilProfile1D soilProfile, string soilGeometry2DName, SurfaceLine2 surfaceLine) { Object objectAsKey = GetObjectAsKey(soilProfile, soilGeometry2DName); SetRedesignedSurfaceLine(objectAsKey, surfaceLine); } /// /// Get Most recent surfaceline /// /// /// private SurfaceLine2 GetMostRecentSurfaceLine(Object objectAsKey) { if (objectAsKey != null) { return redesignedSurfaceLines.ContainsKey(objectAsKey) ? redesignedSurfaceLines[objectAsKey] ?? Location.SurfaceLine : Location.SurfaceLine; // For debugging: following code is the same as above, but better debuggable // SurfaceLine2 surfaceline = Location.SurfaceLine; // if (redesignedSurfaceLines.ContainsKey(objectAsKey)) // { // var s = redesignedSurfaceLines[objectAsKey]; // if (s != null) // { // surfaceline = s; // } // } // return surfaceline; } return null; } /// /// Get Most recent surfaceline /// /// /// /// public SurfaceLine2 GetMostRecentSurfaceLine(SoilProfile soilProfile, string soilGeometry2DName) { var profile1D = soilProfile as SoilProfile1D; Object objectAsKey = GetObjectAsKey(profile1D, soilGeometry2DName); return GetMostRecentSurfaceLine(objectAsKey); } /// /// 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; } /// /// Implementation of ToString /// /// public override string ToString() { return String.Format("Location={0}, ID={1} RiverLevel={2} " + "RiverLevelLow={3} " + "DikeTableHeight={4} " + "SafetyFactorStabilityInnerSlope={5} " + "RequiredSafetyFactorStabilityOuterSlope={6} " + "WaterHeightDecimeringsHoogte= {7} " + "MaxWaterheight={8} " + "PlLineOffsetBelowDikeTopAtRiver={9} " + "PlLineOffsetBelowDikeToeAtPolder={10} " + "PlLineOffsetBelowDikeTopAtPolder={11} " + "PlLineOffsetBelowShoulderBaseInside={12} " + "UsePlLineOffsetBelowDikeCrestMiddle {13} " + "PlLineOffsetBelowDikeCrestMiddle {14} " + "UsePlLineOffsetFactorBelowShoulderCrest {15} " + "PlLineOffsetFactorBelowShoulderCrest {16} " + "HeadPl3={17} " + "HeadPl4={18}", Location.Name, LocationScenarioID, RiverLevel, RiverLevelLow.HasValue ? RiverLevelLow.ToString() : "?", DikeTableHeight.HasValue ? DikeTableHeight.ToString() : "?", ModelFactors.RequiredSafetyFactorStabilityInnerSlope.HasValue ? ModelFactors.RequiredSafetyFactorStabilityInnerSlope.ToString() : "?", ModelFactors.RequiredSafetyFactorStabilityOuterSlope.HasValue ? ModelFactors.RequiredSafetyFactorStabilityOuterSlope.ToString() : "?", WaterHeightDecimeringsHoogte.HasValue ? WaterHeightDecimeringsHoogte.ToString() : "?", MaxWaterLevel.HasValue ? MaxWaterLevel.ToString() : "?", PlLineOffsetBelowDikeTopAtRiver.HasValue ? PlLineOffsetBelowDikeToeAtPolder.ToString() : "?", PlLineOffsetBelowDikeToeAtPolder.HasValue ? MaxWaterLevel.ToString() : "?", PlLineOffsetBelowDikeTopAtPolder.HasValue ? PlLineOffsetBelowDikeTopAtPolder.ToString() : "?", PlLineOffsetBelowShoulderBaseInside.HasValue ? PlLineOffsetBelowShoulderBaseInside.ToString() : "?", UsePlLineOffsetBelowDikeCrestMiddle.HasValue ? UsePlLineOffsetBelowDikeCrestMiddle.ToString() : "?", PlLineOffsetBelowDikeCrestMiddle.HasValue ? PlLineOffsetBelowDikeCrestMiddle.ToString() : "?", UsePlLineOffsetFactorBelowShoulderCrest.HasValue ? UsePlLineOffsetFactorBelowShoulderCrest.ToString() : "?", PlLineOffsetFactorBelowShoulderCrest.HasValue ? PlLineOffsetFactorBelowShoulderCrest.ToString() : "?", HeadPl3.HasValue ? HeadPl3.ToString() : "?", HeadPl4.HasValue ? HeadPl4.ToString() : "?"); } } }