// 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? headPl2; private double? headPl3; private double? headPl4; private double polderLevel; 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; } } /// /// Gets or sets the polder level. /// /// /// The polder level. /// public double PolderLevel { get { return polderLevel; } set { polderLevel = 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 PL2. /// /// /// The head PL2. /// public virtual double? HeadPl2 { get { return headPl2; } set { headPl2 = 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 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} " + "PlLineOffsetBelowDikeTopAtRiver={7} " + "PlLineOffsetBelowDikeToeAtPolder={8} " + "PlLineOffsetBelowDikeTopAtPolder={9} " + "PlLineOffsetBelowShoulderBaseInside={10} " + "UsePlLineOffsetBelowDikeCrestMiddle {11} " + "PlLineOffsetBelowDikeCrestMiddle {12} " + "UsePlLineOffsetFactorBelowShoulderCrest {13} " + "PlLineOffsetFactorBelowShoulderCrest {14} " + "HeadPl2={15} " + "HeadPl3={16} " + "HeadPl4={17} " + "PolderLevel={18} ", Location.Name, LocationScenarioID, RiverLevel, RiverLevelLow.HasValue ? RiverLevelLow.ToString() : "?", DikeTableHeight.HasValue ? DikeTableHeight.ToString() : "?", ModelFactors.RequiredSafetyFactorStabilityInnerSlope, ModelFactors.RequiredSafetyFactorStabilityOuterSlope, PlLineOffsetBelowDikeTopAtRiver, PlLineOffsetBelowDikeToeAtPolder, PlLineOffsetBelowDikeTopAtPolder, PlLineOffsetBelowShoulderBaseInside, UsePlLineOffsetBelowDikeCrestMiddle.HasValue ? UsePlLineOffsetBelowDikeCrestMiddle.ToString() : "?", PlLineOffsetBelowDikeCrestMiddle.HasValue ? PlLineOffsetBelowDikeCrestMiddle.ToString() : "?", UsePlLineOffsetFactorBelowShoulderCrest.HasValue ? UsePlLineOffsetFactorBelowShoulderCrest.ToString() : "?", PlLineOffsetFactorBelowShoulderCrest.HasValue ? PlLineOffsetFactorBelowShoulderCrest.ToString() : "?", HeadPl2.HasValue ? HeadPl2.ToString() : "?", HeadPl3.HasValue ? HeadPl3.ToString() : "?", HeadPl4.HasValue ? HeadPl4.ToString() : "?", PolderLevel); } } }