// Copyright (C) Stichting Deltares 2024. All rights reserved. // // This file is part of the Dam Engine. // // The Dam Engine is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.Linq; using Deltares.DamEngine.Calculators.PlLinesCreator; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.PlLines; using Deltares.DamEngine.Data.General.Sensors; using Deltares.DamEngine.Data.Geotechnics; namespace Deltares.DamEngine.Calculators.KernelWrappers.Common; /// /// Helper for Pl Lines /// public static class PlLinesHelper { /// /// Creates the pl lines. /// /// The location. /// The sub soil scenario. /// The water level. /// The water level river low. /// The sensor pl line creator settings. /// The uplift situation. /// The created Pl-lines public static PlLines CreatePlLinesForStability(Location location, SoilGeometryProbability subSoilScenario, double waterLevel, double? waterLevelRiverLow, SensorPlLineCreatorSettings sensorPlLineCreatorSettings, out UpliftSituation upliftSituation) { PlLines plLines = null; upliftSituation = new UpliftSituation(); switch (location.ModelParametersForPlLines.PlLineCreationMethod) { case PlLineCreationMethod.ExpertKnowledgeLinearInDike: case PlLineCreationMethod.ExpertKnowledgeRRD: plLines = CreatePlLinesForStabilityExpertKnowledge(location, subSoilScenario, waterLevel, waterLevelRiverLow, out upliftSituation); break; case PlLineCreationMethod.Sensors: plLines = CreatePlLinesForStabilitySensors(location, sensorPlLineCreatorSettings); break; default: throw new NotImplementedException($@"Pl-line creation method '{location.ModelParametersForPlLines.PlLineCreationMethod}' is not implemented"); } return plLines; } /// /// Creates the pl lines for stability sensors. /// /// The location. /// The sensor pl-line creator settings. /// public static PlLines CreatePlLinesForStabilitySensors(Location location, SensorPlLineCreatorSettings sensorPlLineCreatorSettings) { PlLines plLines = null; IDictionary actualSensorValues = location.SensorLocation.SensorValues[sensorPlLineCreatorSettings.DateTime][location]; List lineTypes = sensorPlLineCreatorSettings.SensorLocation.Sensors.SelectMany(s => s.PlLineMappings).Distinct().ToList(); var creator = SensorPlLineCreator.CreateInstance(sensorPlLineCreatorSettings.SensorLocation, actualSensorValues, lineTypes); try { plLines = creator.CreateAllPlLines(); } catch (InvalidOperationException e) { throw new SensorPlLineCreatorException(e.Message, e); } return plLines; } /// /// Creates the pl lines. /// /// The location. /// The sub soil scenario. /// The water level. /// The water level river low. /// The uplift situation. /// The created Pl-lines private static PlLines CreatePlLinesForStabilityExpertKnowledge(Location location, SoilGeometryProbability subSoilScenario, double waterLevel, double? waterLevelRiverLow, out UpliftSituation upliftSituation) { var plLinesCreator = new PlLinesCreator.PlLinesCreator { WaterLevelRiverLow = waterLevelRiverLow, IsUseLowWaterLevel = (waterLevelRiverLow != null), WaterLevelRiverHigh = waterLevel, SurfaceLine = location.SurfaceLine, WaterLevelPolder = location.CurrentScenario.PolderLevel, HeadInPlLine2 = location.CurrentScenario.HeadPl2, HeadInPlLine3 = location.CurrentScenario.HeadPl3, HeadInPlLine4 = location.CurrentScenario.HeadPl4, ModelParametersForPlLines = location.ModelParametersForPlLines, SoilProfile = subSoilScenario.SoilProfile1D, SoilProfileType = subSoilScenario.SoilProfileType, SoilProfile2D = subSoilScenario.SoilProfile2D, GaugePlLines = null, // TODO: Operational Gauges = null, // TODO: Operational IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true, // for stability this must be set to true PlLineOffsetBelowDikeTopAtRiver = location.CurrentScenario.PlLineOffsetBelowDikeTopAtRiver, PlLineOffsetBelowDikeTopAtPolder = location.CurrentScenario.PlLineOffsetBelowDikeTopAtPolder, PlLineOffsetBelowShoulderBaseInside = location.CurrentScenario.PlLineOffsetBelowShoulderBaseInside, PlLineOffsetBelowDikeToeAtPolder = location.CurrentScenario.PlLineOffsetBelowDikeToeAtPolder, PlLineOffsetBelowDikeCrestMiddle = location.CurrentScenario.PlLineOffsetBelowDikeCrestMiddle, UsePlLineOffsetFactorBelowShoulderCrest = location.CurrentScenario.UsePlLineOffsetFactorBelowShoulderCrest, DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), SoilList = location.SoilList }; PlLines plLines = plLinesCreator.CreateAllPlLines(location); upliftSituation = new UpliftSituation { Pl3HeadAdjusted = plLinesCreator.Pl3HeadAdjusted, Pl3LocationXMinUplift = plLinesCreator.Pl3LocationXMinUplift, Pl3MinUplift = plLinesCreator.Pl3MinUplift, Pl4HeadAdjusted = plLinesCreator.Pl4HeadAdjusted, Pl4LocationXMinUplift = plLinesCreator.Pl4LocationXMinUplift, Pl4MinUplift = plLinesCreator.Pl4MinUplift, IsUplift = false // must be determined later on; just to avoid compiler error }; return plLines; } /// /// Creates the pl lines. /// /// The time step in date time format. /// The location. /// The soil profile. /// The water level. /// public static PlLines CreatePlLinesForPiping(DateTime timeStepDateTime, Location location, SoilProfile1D soilProfile, double waterLevel) { var plLinesCreator = new PlLinesCreator.PlLinesCreator { WaterLevelRiverHigh = waterLevel, SurfaceLine = location.SurfaceLine, WaterLevelPolder = location.CurrentScenario.PolderLevel, HeadInPlLine2 = location.CurrentScenario.HeadPl2, HeadInPlLine3 = location.CurrentScenario.HeadPl3, HeadInPlLine4 = location.CurrentScenario.HeadPl4, ModelParametersForPlLines = location.ModelParametersForPlLines, SoilProfile = soilProfile, GaugePlLines = null, // TODO: Operational Gauges = null, // TODO: Operational IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = false, // for piping this must be set to false PlLineOffsetBelowDikeTopAtRiver = location.CurrentScenario.PlLineOffsetBelowDikeTopAtRiver, PlLineOffsetBelowDikeTopAtPolder = location.CurrentScenario.PlLineOffsetBelowDikeTopAtPolder, DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil() }; PlLines plLines; if (location.ModelParametersForPlLines.PlLineCreationMethod == PlLineCreationMethod.Sensors) { var sensorPlLineCreatorSettings = new SensorPlLineCreatorSettings(); sensorPlLineCreatorSettings.SensorLocation = location.SensorLocation; sensorPlLineCreatorSettings.DateTime = timeStepDateTime; plLines = CreatePlLinesForStabilitySensors(location, sensorPlLineCreatorSettings); //ToDo Bka: consult with Tom whether we can just use this and just rename or does it really has to be different for Piping? } else { plLines = plLinesCreator.CreateAllPlLines(location); } return plLines; } }