// 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 Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard;
using Deltares.DamEngine.Data.Standard.Calculation;
using Deltares.DamEngine.Data.Standard.Logging;
using Deltares.MacroStability.CSharpWrapper.Input;
using Deltares.MacroStability.CSharpWrapper.Output;
using WaterPressureInterpolationModel = Deltares.DamEngine.Data.Geotechnics.WaterpressureInterpolationModel;
using CharacteristicPoint = Deltares.MacroStability.CSharpWrapper.Input.CharacteristicPointType;
using CharacteristicPointType = Deltares.DamEngine.Data.Geotechnics.CharacteristicPointType;
using WaterPressureInterpolationModelKernel = Deltares.MacroStability.CSharpWrapper.Input.WaterPressureInterpolationModel;
using ShearStrengthModelKernel = Deltares.MacroStability.CSharpWrapper.ShearStrengthModelType;
using Soil = Deltares.MacroStability.CSharpWrapper.Input.Soil;
namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo;
public static class ConversionHelper
{
public static CalculationResult ConvertToDamResultType(CalculationResultType calculationResult)
{
var translationTable = new Dictionary
{
{
CalculationResultType.NoRun, CalculationResult.NoRun
},
{
CalculationResultType.Succeeded, CalculationResult.Succeeded
},
{
CalculationResultType.NoInput, CalculationResult.NoInput
},
{
CalculationResultType.NoLicense, CalculationResult.NoLicense
},
{
CalculationResultType.UserAbort, CalculationResult.UserAbort
},
{
CalculationResultType.InvalidInputStructure, CalculationResult.InvalidInputStructure
},
{
CalculationResultType.InvalidInputData, CalculationResult.InvalidInputData
},
{
CalculationResultType.RunFailed, CalculationResult.RunFailed
},
{
CalculationResultType.UnexpectedError, CalculationResult.UnexpectedError
}
};
return translationTable[calculationResult];
}
public static CalculationResultType ConvertToMacroStabilityResultType(CalculationResult calculationResult)
{
var translationTable = new Dictionary
{
{
CalculationResult.NoRun, CalculationResultType.NoRun
},
{
CalculationResult.Succeeded, CalculationResultType.Succeeded
},
{
CalculationResult.NoInput, CalculationResultType.NoInput
},
{
CalculationResult.NoLicense, CalculationResultType.NoLicense
},
{
CalculationResult.UserAbort, CalculationResultType.UserAbort
},
{
CalculationResult.InvalidInputStructure, CalculationResultType.InvalidInputStructure
},
{
CalculationResult.InvalidInputData, CalculationResultType.InvalidInputData
},
{
CalculationResult.RunFailed, CalculationResultType.RunFailed
},
{
CalculationResult.UnexpectedError, CalculationResultType.UnexpectedError
}
};
return translationTable[calculationResult];
}
#region SearchMethod
/// Converts SearchAlgorithm to MStabSearchMethod.
/// The MacroStability search algorithm.
///
///
public static MStabSearchMethod ConvertToDamSearchMethod(SearchAlgorithm searchAlgorithm)
{
if (searchAlgorithm != SearchAlgorithm.Grid && searchAlgorithm != SearchAlgorithm.Genetic && searchAlgorithm != SearchAlgorithm.BeeswarmAndLevenbergMarquardt)
{
throw new ArgumentException($"Unsupported search algorithm: {searchAlgorithm}");
}
var translationTable = new Dictionary
{
{
SearchAlgorithm.Grid, MStabSearchMethod.Grid
},
{
SearchAlgorithm.BeeswarmAndLevenbergMarquardt, MStabSearchMethod.BeeSwarm
}
};
return translationTable[searchAlgorithm];
}
/// Converts MStabSearchMethod to SearchAlgorithm.
/// The Dam search algorithm.
///
///
public static SearchAlgorithm ConvertToMacroStabilitySearchMethod(MStabSearchMethod mStabSearchMethod)
{
var translationTable = new Dictionary
{
{
MStabSearchMethod.Grid, SearchAlgorithm.Grid
},
{
MStabSearchMethod.BeeSwarm, SearchAlgorithm.BeeswarmAndLevenbergMarquardt
}
};
return translationTable[mStabSearchMethod];
}
#endregion
#region ModelType
/// Converts ModelOption to the MStabModelType.
/// This comes back from the kernel side so any model that can be matched is OK.
/// The model option.
/// the Dam MStabModelType
public static MStabModelType ConvertToMStabModelType(StabilityModelOptionType modelOption)
{
var translationTable = new Dictionary
{
{
StabilityModelOptionType.Bishop, MStabModelType.Bishop
},
{
StabilityModelOptionType.UpliftVan, MStabModelType.UpliftVan
}
//{MacroStability.CSharpWrapper.Output.StabilityModelOption.Spencer, MStabModelType.UpliftSpencerWti}
};
return translationTable[modelOption];
}
/// Converts to ModelOptions type.
/// the MStabModelType.
/// the MacroStability ModelOption
///
public static StabilityModelOptionType ConvertToModelOptions(MStabModelType mStabModelType)
{
// For the Macrostability kernel, the only supported options for now are Bishop and UpliftVan.
if (mStabModelType != MStabModelType.UpliftVan && mStabModelType != MStabModelType.Bishop)
{
throw new ArgumentException($"Unsupported MStabModelType: {mStabModelType}");
}
var translationTable = new Dictionary
{
{
MStabModelType.UpliftVan, StabilityModelOptionType.UpliftVan
},
{
MStabModelType.Bishop, StabilityModelOptionType.Bishop
}
};
return translationTable[mStabModelType];
}
/// Converts to ModelOptions type.
/// the MStabModelType.
/// the MacroStability ModelOption
///
public static StabilityModelOptionType ConvertToModelOptionsOutput(MStabModelType mStabModelType)
{
// For the Macrostability kernel, the only supported options for now are Bishop and UpliftVan.
if (mStabModelType != MStabModelType.Bishop && mStabModelType != MStabModelType.UpliftVan)
{
throw new ArgumentException($"Unsupported MStabModelType: {mStabModelType}");
}
var translationTable = new Dictionary
{
{
MStabModelType.Bishop, StabilityModelOptionType.Bishop
},
{
MStabModelType.UpliftVan, StabilityModelOptionType.UpliftVan
}
};
return translationTable[mStabModelType];
}
#endregion
#region GridOrientation
/// Converts to MStabGridPosition.
/// The grid orientation.
///
public static MStabGridPosition ConvertToMStabGridPosition(Orientation gridOrientation)
{
var translationTable = new Dictionary
{
{
Orientation.Inwards, MStabGridPosition.Right
},
{
Orientation.Outwards, MStabGridPosition.Left
}
};
return translationTable[gridOrientation];
}
/// Converts to GridOrientation.
/// The MStabGridPosition.
///
public static Orientation ConvertToGridOrientation(MStabGridPosition mStabGridPosition)
{
var translationTable = new Dictionary
{
{
MStabGridPosition.Right, Orientation.Inwards
},
{
MStabGridPosition.Left, Orientation.Outwards
}
};
return translationTable[mStabGridPosition];
}
#endregion
#region Soil
/// Converts to MacroStability soil.
/// The Dam soil.
/// The MacroStability Soil.
public static Soil ConvertToMacroStabilitySoil(Data.Geotechnics.Soil soil)
{
var macroStabilitySoil = new Soil
{
Name = soil.Name,
AbovePhreaticLevel = soil.AbovePhreaticLevel,
BelowPhreaticLevel = soil.BelowPhreaticLevel,
Cohesion = soil.Cohesion,
FrictionAngle = 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 List(),
SuTable = new List()
};
if (soil.ShearStrengthModel != null)
{
macroStabilitySoil.ShearStrengthAbovePhreaticLevelModel = ConvertToMacroStabilityShearStrengthModel(soil.ShearStrengthModel.Value);
macroStabilitySoil.ShearStrengthBelowPhreaticLevelModel = ConvertToMacroStabilityShearStrengthModel(soil.ShearStrengthModel.Value);
}
if (soil.SigmaTauCurve != null)
{
foreach (SigmaTauPoint point in soil.SigmaTauCurve.Points)
{
macroStabilitySoil.SigmaTauTable.Add(new SigmaTauTablePoint
{
Sigma = point.Sigma,
Tau = point.Tau
});
}
}
if (soil.SuTableCurve != null)
{
foreach (SigmaSuPoint point in soil.SuTableCurve.Points)
{
macroStabilitySoil.SuTable.Add(new SuTablePoint()
{
EffectiveStress = point.Sigma,
Su = point.Su
});
}
}
switch (soil.DilatancyType)
{
case DilatancyType.MinusPhi:
macroStabilitySoil.Dilatancy = -macroStabilitySoil.FrictionAngle; // -Phi (FrictionAngle)
break;
case DilatancyType.Phi:
macroStabilitySoil.Dilatancy = macroStabilitySoil.FrictionAngle; // Phi (FrictionAngle)
break;
default:
macroStabilitySoil.Dilatancy = 0.0; // Zero and default
break;
}
return macroStabilitySoil;
}
/// Converts to Dam soil.
/// The MacroStability soil.
/// The Dam soil.
///
public static Data.Geotechnics.Soil ConvertToDamSoil(Soil soil)
{
var tolerance = 0.00001;
var damSoil = new Data.Geotechnics.Soil
{
Name = soil.Name,
AbovePhreaticLevel = soil.AbovePhreaticLevel,
BelowPhreaticLevel = soil.BelowPhreaticLevel,
Cohesion = soil.Cohesion,
FrictionAngle = soil.FrictionAngle,
RatioCuPc = soil.RatioCuPc,
StrengthIncreaseExponent = soil.StrengthIncreaseExponent,
//Todo #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 (SigmaTauTablePoint 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 (SuTablePoint point in soil.SuTable)
{
damSoil.SuTableCurve.Points.Add(new SigmaSuPoint()
{
Sigma = point.EffectiveStress,
Su = point.Su
});
}
}
if (soil.Dilatancy.AlmostEquals(soil.FrictionAngle, tolerance))
{
damSoil.DilatancyType = DilatancyType.Phi;
}
else if (soil.Dilatancy.AlmostEquals(-soil.FrictionAngle, tolerance))
{
damSoil.DilatancyType = DilatancyType.MinusPhi;
}
else if (soil.Dilatancy.AlmostEquals(0.0, tolerance))
{
damSoil.DilatancyType = DilatancyType.Zero;
}
else
{
throw new FormatException($"Cannot determine DilatancyType; Dilatancy = {soil.Dilatancy}, FrictionAngle = {soil.FrictionAngle}");
}
return damSoil;
}
/// Converts to dam ShearStrengthModel.
/// The kernel ShearStrengthModel.
///
public static ShearStrengthModel ConvertToDamShearStrengthModel(ShearStrengthModelKernel kernelShearStrengthModel)
{
var translationTable = new Dictionary
{
{
ShearStrengthModelKernel.MohrCoulomb, ShearStrengthModel.CPhi
},
{
ShearStrengthModelKernel.Shansep, ShearStrengthModel.SuCalculated
},
{
ShearStrengthModelKernel.SigmaTauTable, ShearStrengthModel.SigmaTauCurve
},
{
ShearStrengthModelKernel.SuTable, ShearStrengthModel.SuTable
}
};
return translationTable[kernelShearStrengthModel];
}
/// Converts to macro stability ShearStrengthModel.
/// The dam ShearStrengthModel.
///
///
public static ShearStrengthModelKernel ConvertToMacroStabilityShearStrengthModel(ShearStrengthModel damShearStrengthModel)
{
var translationTable = new Dictionary
{
{
ShearStrengthModel.CPhi, ShearStrengthModelKernel.MohrCoulomb
},
{
ShearStrengthModel.SuCalculated, ShearStrengthModelKernel.Shansep
},
{
ShearStrengthModel.SigmaTauCurve, ShearStrengthModelKernel.SigmaTauTable
},
{
ShearStrengthModel.SuTable, ShearStrengthModelKernel.SuTable
}
};
return translationTable[damShearStrengthModel];
}
#endregion
#region WaterpressureInterpolationModel
/// Converts to macro stability waterpressure interpolation model.
/// The waterpressure interpolation model.
///
public static WaterPressureInterpolationModelKernel ConvertToMacroStabilityWaterpressureInterpolationModel(WaterPressureInterpolationModel waterpressureInterpolationModel)
{
var translationTable = new Dictionary
{
{
WaterPressureInterpolationModel.Automatic, WaterPressureInterpolationModelKernel.Automatic
},
{
WaterPressureInterpolationModel.Hydrostatic, WaterPressureInterpolationModelKernel.Hydrostatic
}
};
return translationTable[waterpressureInterpolationModel];
}
/// Converts to dam waterpressure interpolation model.
/// The waterpressure interpolation model.
///
public static WaterpressureInterpolationModel ConvertToDamWaterpressureInterpolationModel(WaterPressureInterpolationModelKernel waterpressureInterpolationModel)
{
var translationTable = new Dictionary
{
{
WaterPressureInterpolationModelKernel.Automatic, WaterPressureInterpolationModel.Automatic
},
{
WaterPressureInterpolationModelKernel.Hydrostatic, WaterPressureInterpolationModel.Hydrostatic
}
};
return translationTable[waterpressureInterpolationModel];
}
#endregion
#region CharacteristicPointType
/// Converts the type of to dam characteristic point.
/// Type of the kernel characteristic point.
///
public static CharacteristicPointType ConvertToDamCharacteristicPointType(CharacteristicPoint kernelCharacteristicPointType)
{
var translationTable = new Dictionary
{
{
CharacteristicPoint.BottomDitchDikeSide, CharacteristicPointType.BottomDitchDikeSide
},
{
CharacteristicPoint.BottomDitchPolderSide, CharacteristicPointType.BottomDitchPolderSide
},
{
CharacteristicPoint.DikeToeAtPolder, CharacteristicPointType.DikeToeAtPolder
},
{
CharacteristicPoint.DikeToeAtRiver, CharacteristicPointType.DikeToeAtRiver
},
{
CharacteristicPoint.DikeTopAtPolder, CharacteristicPointType.DikeTopAtPolder
},
{
CharacteristicPoint.DikeTopAtRiver, CharacteristicPointType.DikeTopAtRiver
},
{
CharacteristicPoint.DitchDikeSide, CharacteristicPointType.DitchDikeSide
},
{
CharacteristicPoint.DitchPolderSide, CharacteristicPointType.DitchPolderSide
},
{
CharacteristicPoint.None, CharacteristicPointType.None
},
{
CharacteristicPoint.ShoulderBaseInside, CharacteristicPointType.ShoulderBaseInside
},
{
CharacteristicPoint.ShoulderBaseOutside, CharacteristicPointType.ShoulderBaseOutside
},
{
CharacteristicPoint.ShoulderTopInside, CharacteristicPointType.ShoulderTopInside
},
{
CharacteristicPoint.ShoulderTopOutside, CharacteristicPointType.ShoulderTopOutside
},
{
CharacteristicPoint.SurfaceLevelInside, CharacteristicPointType.SurfaceLevelInside
},
{
CharacteristicPoint.SurfaceLevelOutside, CharacteristicPointType.SurfaceLevelOutside
},
{
CharacteristicPoint.TrafficLoadInside, CharacteristicPointType.TrafficLoadInside
},
{
CharacteristicPoint.TrafficLoadOutside, CharacteristicPointType.TrafficLoadOutside
}
};
return translationTable[kernelCharacteristicPointType];
}
/// Converts the type of to macro stability characteristic point.
/// Type of the dam characteristic point.
///
public static CharacteristicPoint ConvertToMacroStabilityCharacteristicPointType(CharacteristicPointType damCharacteristicPointType)
{
var translationTable = new Dictionary
{
{
CharacteristicPointType.BottomDitchPolderSide, CharacteristicPoint.BottomDitchPolderSide
},
{
CharacteristicPointType.BottomDitchDikeSide, CharacteristicPoint.BottomDitchDikeSide
},
{
CharacteristicPointType.DikeToeAtPolder, CharacteristicPoint.DikeToeAtPolder
},
{
CharacteristicPointType.DikeToeAtRiver, CharacteristicPoint.DikeToeAtRiver
},
{
CharacteristicPointType.DikeTopAtPolder, CharacteristicPoint.DikeTopAtPolder
},
{
CharacteristicPointType.DikeTopAtRiver, CharacteristicPoint.DikeTopAtRiver
},
{
CharacteristicPointType.DitchDikeSide, CharacteristicPoint.DitchDikeSide
},
{
CharacteristicPointType.DitchPolderSide, CharacteristicPoint.DitchPolderSide
},
{
CharacteristicPointType.None, CharacteristicPoint.None
},
{
CharacteristicPointType.ShoulderBaseInside, CharacteristicPoint.ShoulderBaseInside
},
{
CharacteristicPointType.ShoulderBaseOutside, CharacteristicPoint.ShoulderBaseOutside
},
{
CharacteristicPointType.ShoulderTopInside, CharacteristicPoint.ShoulderTopInside
},
{
CharacteristicPointType.ShoulderTopOutside, CharacteristicPoint.ShoulderTopOutside
},
{
CharacteristicPointType.SurfaceLevelInside, CharacteristicPoint.SurfaceLevelInside
},
{
CharacteristicPointType.SurfaceLevelOutside, CharacteristicPoint.SurfaceLevelOutside
},
{
CharacteristicPointType.TrafficLoadInside, CharacteristicPoint.TrafficLoadInside
},
{
CharacteristicPointType.TrafficLoadOutside, CharacteristicPoint.TrafficLoadOutside
}
};
return translationTable[damCharacteristicPointType];
}
#endregion
#region LogMessages
///
/// Converts the kernel validation result type to log message type of DamEngine.
///
/// Type of the message.
///
public static MessageType ConvertLogMessageTypeToKernelLogMessageType(LogMessageType messageType)
{
var translationTable = new Dictionary
{
{
LogMessageType.Info, MessageType.Info
},
{
LogMessageType.Warning, MessageType.Warning
},
{
LogMessageType.Error, MessageType.Error
}
};
return translationTable[messageType];
}
///
/// Converts the kernel log message type to log message type of DamEngine.
///
/// Type of the message.
///
public static LogMessageType ConvertKernelLogMessageTypeToLogMessageType(MessageType messageType)
{
var translationTable = new Dictionary
{
{
MessageType.Info, LogMessageType.Info
},
{
MessageType.Warning, LogMessageType.Warning
},
{
MessageType.Error, LogMessageType.Error
}
};
return translationTable[messageType];
}
#endregion
}