// Copyright (C) Stichting Deltares 2025. 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 Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.Geotechnics; using Deltares.MacroStability.Io.XmlInput; using CharacteristicPointType = Deltares.MacroStability.Io.XmlInput.CharacteristicPointType; namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo; public static class InputConversionHelper { /// Converts SearchAlgorithm to Dam SearchMethod. /// The MacroStability search algorithm. /// StabilitySearchMethod /// public static StabilitySearchMethod ConvertToDamSearchMethod(SearchAlgorithmType searchAlgorithm) { if (searchAlgorithm != SearchAlgorithmType.Grid && searchAlgorithm != SearchAlgorithmType.Genetic && searchAlgorithm != SearchAlgorithmType.BeeswarmAndLevenbergMarquardt) { throw new ArgumentException($"Unsupported search algorithm: {searchAlgorithm}"); } var translationTable = new Dictionary { { SearchAlgorithmType.Grid, StabilitySearchMethod.Grid }, { SearchAlgorithmType.BeeswarmAndLevenbergMarquardt, StabilitySearchMethod.BeeSwarm } }; return translationTable[searchAlgorithm]; } /// Converts Dam SearchMethod to Macro Stability SearchAlgorithm. /// The Dam search algorithm. /// SearchAlgorithmType /// public static SearchAlgorithmType ConvertToMacroStabilitySearchMethod(StabilitySearchMethod stabilitySearchMethod) { var translationTable = new Dictionary { { StabilitySearchMethod.Grid, SearchAlgorithmType.Grid }, { StabilitySearchMethod.BeeSwarm, SearchAlgorithmType.BeeswarmAndLevenbergMarquardt } }; return translationTable[stabilitySearchMethod]; } /// Converts to ModelOptions type. /// the Dam StabilityModelType. /// the MacroStability ModelOption /// public static StabilityModelOption ConvertToMacroStabilityModelOption(StabilityModelType stabilityModelType) { // For the Macrostability kernel, the only supported options for now are Bishop and UpliftVan. if (stabilityModelType != StabilityModelType.UpliftVan && stabilityModelType != StabilityModelType.Bishop) { throw new ArgumentException($"Unsupported MStabModelType: {stabilityModelType}"); } var translationTable = new Dictionary { { StabilityModelType.UpliftVan, StabilityModelOption.UpliftVan }, { StabilityModelType.Bishop, StabilityModelOption.Bishop } }; return translationTable[stabilityModelType]; } /// Converts ModelOption to the DamModelType. /// This comes back from the kernel side so any model that can be matched is OK. /// The model option. /// the Dam MStabModelType public static StabilityModelType ConvertToDamStabilityModelType(StabilityModelOption stabilityModelOption) { var translationTable = new Dictionary { { StabilityModelOption.Bishop, StabilityModelType.Bishop }, { StabilityModelOption.UpliftVan, StabilityModelType.UpliftVan } }; return translationTable[stabilityModelOption]; } /// Converts to MacroStability GridOrientation. /// The Dam GridPosition. /// OrientationType public static OrientationType ConvertToMacroStabilityGridOrientation(StabilityGridPosition stabilityGridPosition) { var translationTable = new Dictionary { { StabilityGridPosition.Right, OrientationType.Inwards }, { StabilityGridPosition.Left, OrientationType.Outwards } }; return translationTable[stabilityGridPosition]; } /// Converts to Dam GridPosition. /// The grid orientation. /// StabilityGridPosition public static StabilityGridPosition ConvertToDamGridPosition(OrientationType gridOrientation) { var translationTable = new Dictionary { { OrientationType.Inwards, StabilityGridPosition.Right }, { OrientationType.Outwards, StabilityGridPosition.Left } }; return translationTable[gridOrientation]; } /// Converts the type of to macro stability characteristic point. /// Type of the dam characteristic point. /// CharacteristicPointType (Macro stability) public static CharacteristicPointType ConvertToMacroStabilityCharacteristicPointType(Data.Geotechnics.CharacteristicPointType damCharacteristicPointType) { var translationTable = new Dictionary { { Data.Geotechnics.CharacteristicPointType.BottomDitchPolderSide, CharacteristicPointType.BottomDitchPolderSide }, { Data.Geotechnics.CharacteristicPointType.BottomDitchDikeSide, CharacteristicPointType.BottomDitchDikeSide }, { Data.Geotechnics.CharacteristicPointType.DikeToeAtPolder, CharacteristicPointType.DikeToeAtPolder }, { Data.Geotechnics.CharacteristicPointType.DikeToeAtRiver, CharacteristicPointType.DikeToeAtRiver }, { Data.Geotechnics.CharacteristicPointType.DikeTopAtPolder, CharacteristicPointType.DikeTopAtPolder }, { Data.Geotechnics.CharacteristicPointType.DikeTopAtRiver, CharacteristicPointType.DikeTopAtRiver }, { Data.Geotechnics.CharacteristicPointType.DitchDikeSide, CharacteristicPointType.DitchDikeSide }, { Data.Geotechnics.CharacteristicPointType.DitchPolderSide, CharacteristicPointType.DitchPolderSide }, { Data.Geotechnics.CharacteristicPointType.DikeLine, CharacteristicPointType.None }, { Data.Geotechnics.CharacteristicPointType.None, CharacteristicPointType.None }, { Data.Geotechnics.CharacteristicPointType.ShoulderBaseInside, CharacteristicPointType.ShoulderBaseInside }, { Data.Geotechnics.CharacteristicPointType.ShoulderBaseOutside, CharacteristicPointType.ShoulderBaseOutside }, { Data.Geotechnics.CharacteristicPointType.ShoulderTopInside, CharacteristicPointType.ShoulderTopInside }, { Data.Geotechnics.CharacteristicPointType.ShoulderTopOutside, CharacteristicPointType.ShoulderTopOutside }, { Data.Geotechnics.CharacteristicPointType.SurfaceLevelInside, CharacteristicPointType.SurfaceLevelInside }, { Data.Geotechnics.CharacteristicPointType.SurfaceLevelOutside, CharacteristicPointType.SurfaceLevelOutside }, { Data.Geotechnics.CharacteristicPointType.TrafficLoadInside, CharacteristicPointType.TrafficLoadInside }, { Data.Geotechnics.CharacteristicPointType.TrafficLoadOutside, CharacteristicPointType.TrafficLoadOutside } }; return translationTable[damCharacteristicPointType]; } /// Converts the type of macro stability characteristic point to dam type. /// Type of the dam characteristic point. /// CharacteristicPointType (DamEngine) public static Data.Geotechnics.CharacteristicPointType ConvertToDamCharacteristicPointType(CharacteristicPointType kernelCharacteristicPointType) { var translationTable = new Dictionary { { CharacteristicPointType.BottomDitchPolderSide, Data.Geotechnics.CharacteristicPointType.BottomDitchPolderSide }, { CharacteristicPointType.BottomDitchDikeSide, Data.Geotechnics.CharacteristicPointType.BottomDitchDikeSide }, { CharacteristicPointType.DikeToeAtPolder, Data.Geotechnics.CharacteristicPointType.DikeToeAtPolder }, { CharacteristicPointType.DikeToeAtRiver, Data.Geotechnics.CharacteristicPointType.DikeToeAtRiver }, { CharacteristicPointType.DikeTopAtPolder, Data.Geotechnics.CharacteristicPointType.DikeTopAtPolder }, { CharacteristicPointType.DikeTopAtRiver, Data.Geotechnics.CharacteristicPointType.DikeTopAtRiver }, { CharacteristicPointType.DitchDikeSide, Data.Geotechnics.CharacteristicPointType.DitchDikeSide }, { CharacteristicPointType.DitchPolderSide, Data.Geotechnics.CharacteristicPointType.DitchPolderSide }, { CharacteristicPointType.None, Data.Geotechnics.CharacteristicPointType.None }, { CharacteristicPointType.ShoulderBaseInside, Data.Geotechnics.CharacteristicPointType.ShoulderBaseInside }, { CharacteristicPointType.ShoulderBaseOutside, Data.Geotechnics.CharacteristicPointType.ShoulderBaseOutside }, { CharacteristicPointType.ShoulderTopInside, Data.Geotechnics.CharacteristicPointType.ShoulderTopInside }, { CharacteristicPointType.ShoulderTopOutside, Data.Geotechnics.CharacteristicPointType.ShoulderTopOutside }, { CharacteristicPointType.SurfaceLevelInside, Data.Geotechnics.CharacteristicPointType.SurfaceLevelInside }, { CharacteristicPointType.SurfaceLevelOutside, Data.Geotechnics.CharacteristicPointType.SurfaceLevelOutside }, { CharacteristicPointType.TrafficLoadInside, Data.Geotechnics.CharacteristicPointType.TrafficLoadInside }, { CharacteristicPointType.TrafficLoadOutside, Data.Geotechnics.CharacteristicPointType.TrafficLoadOutside } }; return translationTable[kernelCharacteristicPointType]; } /// Converts to MacroStability soil. /// The Dam soil. /// The MacroStability Soil. public static SoilType ConvertToMacroStabilitySoil(Soil soil) { var macroStabilitySoil = new SoilType { Name = soil.Name, AbovePhreaticLevel = soil.AbovePhreaticLevel, BelowPhreaticLevel = soil.BelowPhreaticLevel, Cohesion = soil.Cohesion, FrictionAngle = soil.FrictionAngle, Dilatancy = soil.FrictionAngle, RatioCuPc = soil.RatioCuPc, StrengthIncreaseExponent = soil.ShearStrengthModel == ShearStrengthModel.SuTable && double.IsNaN(soil.StrengthIncreaseExponent) ? 1.0 : soil.StrengthIncreaseExponent, // can't be NaN in MAC kernel because used for multi-stages UseSoilClassification = false, // Soil type is not given so make sure it is not used. BondStressCurve = null, // these are not supported in DAM so set to null. SigmaTauTable = new SoilTypeSigmaTauTablePoint[soil.SigmaTauCurve.Points.Count], SuTable = new SoilTypeSuTablePoint[soil.SuTableCurve.Points.Count] }; if (soil.ShearStrengthModel != null) { macroStabilitySoil.ShearStrengthAbovePhreaticLevelModel = ConvertToMacroStabilityShearStrengthModel(soil.ShearStrengthModel.Value); macroStabilitySoil.ShearStrengthBelowPhreaticLevelModel = ConvertToMacroStabilityShearStrengthModel(soil.ShearStrengthModel.Value); } if (soil.SigmaTauCurve != null) { var i = 0; foreach (SigmaTauPoint point in soil.SigmaTauCurve.Points) { var tablePoint = new SoilTypeSigmaTauTablePoint { Sigma = point.Sigma, Tau = point.Tau }; macroStabilitySoil.SigmaTauTable[i] = tablePoint; i++; } } if (soil.SuTableCurve != null) { var i = 0; foreach (SigmaSuPoint point in soil.SuTableCurve.Points) { var tablePoint = new SoilTypeSuTablePoint { Su = point.Su, EffectiveStress = point.Sigma }; macroStabilitySoil.SuTable[i] = tablePoint; i++; } } return macroStabilitySoil; } /// Converts to Dam soil. /// The MacroStability soil. /// The Dam soil. /// public static Soil ConvertToDamSoil(SoilType soil) { var damSoil = new Soil { Name = soil.Name, AbovePhreaticLevel = soil.AbovePhreaticLevel, BelowPhreaticLevel = soil.BelowPhreaticLevel, Cohesion = soil.Cohesion, FrictionAngle = soil.FrictionAngle, RatioCuPc = soil.RatioCuPc, StrengthIncreaseExponent = soil.StrengthIncreaseExponent, //#Bka We keep this as "truth" for now. But maybe Dam should become above/below too ShearStrengthModel = ConvertToDamShearStrengthModel(soil.ShearStrengthAbovePhreaticLevelModel) }; if (soil.SigmaTauTable != null) { damSoil.SigmaTauCurve = new SigmaTauCurve(); foreach (SoilTypeSigmaTauTablePoint point in soil.SigmaTauTable) { damSoil.SigmaTauCurve.Points.Add(new SigmaTauPoint { Sigma = point.Sigma, Tau = point.Tau }); } } if (soil.SuTable != null) { damSoil.SuTableCurve = new SuTableCurve(); foreach (SoilTypeSuTablePoint point in soil.SuTable) { damSoil.SuTableCurve.Points.Add(new SigmaSuPoint { Sigma = point.EffectiveStress, Su = point.Su }); } } return damSoil; } /// Converts to macro stability water pressure interpolation model. /// The water pressure interpolation model. /// WaterPressureInterpolationModelType public static WaterPressureInterpolationModelType ConvertToMacroStabilityWaterPressureInterpolationModel(WaterpressureInterpolationModel waterPressureInterpolationModel) { var translationTable = new Dictionary { { WaterpressureInterpolationModel.Automatic, WaterPressureInterpolationModelType.Automatic }, { WaterpressureInterpolationModel.Hydrostatic, WaterPressureInterpolationModelType.Hydrostatic } }; return translationTable[waterPressureInterpolationModel]; } /// Converts to dam water pressure interpolation model. /// The water pressure interpolation model. /// WaterpressureInterpolationModel public static WaterpressureInterpolationModel ConvertToDamWaterPressureInterpolationModel(WaterPressureInterpolationModelType waterpressureInterpolationModel) { var translationTable = new Dictionary { { WaterPressureInterpolationModelType.Automatic, WaterpressureInterpolationModel.Automatic }, { WaterPressureInterpolationModelType.Hydrostatic, WaterpressureInterpolationModel.Hydrostatic } }; return translationTable[waterpressureInterpolationModel]; } /// Converts to macro stability ShearStrengthModel. /// The dam ShearStrengthModel. /// ShearStrengthModelType /// private static ShearStrengthModelType ConvertToMacroStabilityShearStrengthModel(ShearStrengthModel damShearStrengthModel) { var translationTable = new Dictionary { { ShearStrengthModel.CPhi, ShearStrengthModelType.MohrCoulomb }, { ShearStrengthModel.SuCalculated, ShearStrengthModelType.Shansep }, { ShearStrengthModel.SigmaTauCurve, ShearStrengthModelType.SigmaTauTable }, { ShearStrengthModel.SuTable, ShearStrengthModelType.SuTable } }; return translationTable[damShearStrengthModel]; } /// Converts to dam ShearStrengthModel. /// The kernel ShearStrengthModel. /// ShearStrengthModel private static ShearStrengthModel ConvertToDamShearStrengthModel(ShearStrengthModelType kernelShearStrengthModel) { var translationTable = new Dictionary { { ShearStrengthModelType.MohrCoulomb, ShearStrengthModel.CPhi }, { ShearStrengthModelType.Shansep, ShearStrengthModel.SuCalculated }, { ShearStrengthModelType.SigmaTauTable, ShearStrengthModel.SigmaTauCurve }, { ShearStrengthModelType.SuTable, ShearStrengthModel.SuTable } }; return translationTable[kernelShearStrengthModel]; } }