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