// 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.Collections.Generic;
using System.Linq;
using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards;
using Deltares.DamEngine.Data.General.Results;
using Deltares.DamEngine.Data.Standard.Logging;
using Deltares.MacroStability.CSharpWrapper;
using Deltares.MacroStability.CSharpWrapper.Output;
using MacroStabilityOutput = Deltares.MacroStability.CSharpWrapper.Output.MacroStabilityOutput;
namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo;
///
/// Fills the MacroStabilityWrapper output with Fills the engine results
///
public class FillMacroStabilityWrapperOutputFromEngine
{
public static MacroStabilityOutput FillMacroStabilityWrapperOutput(MacroStabilityInwards.MacroStabilityOutput output, List logMessages)
{
var kernelOutput = new MacroStabilityOutput();
kernelOutput.ResultType = ConversionHelper.ConvertToMacroStabilityResultType(output.CalculationResult);
kernelOutput.StabilityOutput = new StabilityOutput();
if (kernelOutput.ResultType == CalculationResultType.Succeeded)
{
MacroStabilityOutputItem outputItem = output.StabilityOutputItems.First();
kernelOutput.StabilityOutput.SafetyFactor = outputItem.SafetyFactor;
kernelOutput.StabilityOutput.ModelOptionType = ConversionHelper.ConvertToModelOptionsOutput(outputItem.StabilityModelType);
switch (kernelOutput.StabilityOutput.ModelOptionType)
{
case StabilityModelOptionType.Bishop:
kernelOutput.PreprocessingOutputBase = new BishopPreprocessingOutput();
break;
case StabilityModelOptionType.UpliftVan:
kernelOutput.PreprocessingOutputBase = new UpliftVanPreprocessingOutput();
break;
}
if (kernelOutput.StabilityOutput.ModelOptionType == StabilityModelOptionType.Bishop && outputItem.ActiveCenterPoint != null)
{
FillBishop(outputItem, kernelOutput);
}
if (kernelOutput.StabilityOutput.ModelOptionType == StabilityModelOptionType.UpliftVan && outputItem.ActiveCenterPoint != null && outputItem.PassiveCenterPoint != null)
{
FillUpliftVan(outputItem, kernelOutput);
}
if ((kernelOutput.StabilityOutput.ModelOptionType == StabilityModelOptionType.Bishop ||
kernelOutput.StabilityOutput.ModelOptionType == StabilityModelOptionType.UpliftVan) &&
outputItem.ResultSlices != null)
{
FillSlices(outputItem, kernelOutput);
}
}
else
{
kernelOutput.StabilityOutput.SafetyFactor = double.NaN;
}
if (logMessages != null && logMessages.Any())
{
var messagesOutput = new List();
foreach (LogMessage logMessage in logMessages)
{
var message = new Message();
message.Content = logMessage.Message;
message.MessageType = ConversionHelper.ConvertLogMessageTypeToKernelLogMessageType(logMessage.MessageType);
messagesOutput.Add(message);
}
kernelOutput.StabilityOutput.Messages = messagesOutput;
}
return kernelOutput;
}
private static void FillSlices(MacroStabilityOutputItem outputItem, MacroStabilityOutput kernelOutput)
{
var slices = new List();
foreach (StabilityResultSlice resultSlice in outputItem.ResultSlices)
{
var slice = new Slice
{
TopLeftPoint = new Point2D(resultSlice.TopLeftPoint.X, resultSlice.TopLeftPoint.Z),
TopRightPoint = new Point2D(resultSlice.TopRightPoint.X, resultSlice.TopRightPoint.Z),
BottomLeftPoint = new Point2D(resultSlice.BottomLeftPoint.X, resultSlice.BottomLeftPoint.Z),
BottomRightPoint = new Point2D(resultSlice.BottomRightPoint.X, resultSlice.BottomRightPoint.Z),
Name = resultSlice.Name,
Width = resultSlice.Width,
ArcLength = resultSlice.ArcLength,
TopAngle = resultSlice.TopAngle,
BottomAngle = resultSlice.BottomAngle,
CohesionInput = resultSlice.CohesionInput,
CohesionOutput = resultSlice.CohesionOutput,
FrictionAngleInput = resultSlice.FrictionAngleInput,
FrictionAngleOutput = resultSlice.FrictionAngleOutput,
YieldStress = resultSlice.YieldStress,
OCR = resultSlice.OCR,
POP = resultSlice.POP,
DegreeOfConsolidationPorePressure = resultSlice.DegreeOfConsolidationPorePressure,
PorePressureDueToDegreeOfConsolidationLoad = resultSlice.PorePressureDueToDegreeOfConsolidationLoad,
DilatancyInput = resultSlice.DilatancyInput,
ExternalLoad = resultSlice.ExternalLoad,
HydrostaticPorePressure = resultSlice.HydrostaticPorePressure,
LeftForce = resultSlice.LeftForce,
LeftForceAngle = resultSlice.LeftForceAngle,
LeftForceY = resultSlice.LeftForceY,
RightForce = resultSlice.RightForce,
RightForceAngle = resultSlice.RightForceAngle,
RightForceY = resultSlice.RightForceY,
LoadStress = resultSlice.LoadStress,
NormalStress = resultSlice.NormalStress,
PorePressure = resultSlice.PorePressure,
HorizontalPorePressure = resultSlice.HorizontalPorePressure,
VerticalPorePressure = resultSlice.VerticalPorePressure,
PiezometricPorePressure = resultSlice.PiezometricPorePressure,
EffectiveStress = resultSlice.EffectiveStress,
ExcessPorePressure = resultSlice.ExcessPorePressure,
ShearStressInput = resultSlice.ShearStressInput,
ShearStressOutput = resultSlice.ShearStressOutput,
SoilStress = resultSlice.SoilStress,
TotalPorePressure = resultSlice.TotalPorePressure,
TotalStress = resultSlice.TotalStress,
Weight = resultSlice.Weight,
SuInput = resultSlice.SuInput,
SuOutput = resultSlice.SuOutput,
ShearStrengthModelType = ConversionHelper.ConvertToMacroStabilityShearStrengthModel(resultSlice.ShearStrengthModel),
HorizontalSoilQuakeStress = resultSlice.HorizontalSoilQuakeStress,
StrengthIncreaseExponent = resultSlice.StrengthIncreaseExponent,
UpliftFactor = resultSlice.UpliftFactor,
VerticalSoilQuakeStress = resultSlice.VerticalSoilQuakeStress,
WaterQuakeStress = resultSlice.WaterQuakeStress,
UpliftReductionFactor = resultSlice.UpliftReductionFactor,
RatioCuPc = resultSlice.RatioCuPc,
ResultantForce = resultSlice.ResultantForce,
ResultantMoment = resultSlice.ResultantMoment,
ResultantAngle = resultSlice.ResultantAngle
};
slices.Add(slice);
}
kernelOutput.StabilityOutput.MinimumSafetyCurve.Slices = slices;
}
private static void FillUpliftVan(MacroStabilityOutputItem outputItem, MacroStabilityOutput kernelOutput)
{
var dualSlidingCircleMinimumSafetyCurve = new DualSlidingCircleMinimumSafetyCurve
{
ActiveCircleCenter = new Point2D(outputItem.ActiveCenterPoint.X, outputItem.ActiveCenterPoint.Z),
ActiveCircleRadius = outputItem.ActiveCenterPointRadius,
PassiveCircleCenter = new Point2D(outputItem.PassiveCenterPoint.X, outputItem.PassiveCenterPoint.Z),
PassiveCircleRadius = outputItem.PassiveCenterPointRadius
};
kernelOutput.StabilityOutput.MinimumSafetyCurve = dualSlidingCircleMinimumSafetyCurve;
}
private static void FillBishop(MacroStabilityOutputItem outputItem, MacroStabilityOutput kernelOutput)
{
var slidingCircleMinimumSafetyCurve = new SlidingCircleMinimumSafetyCurve
{
Center = new Point2D(outputItem.ActiveCenterPoint.X, outputItem.ActiveCenterPoint.Z),
Radius = outputItem.ActiveCenterPointRadius
};
kernelOutput.StabilityOutput.MinimumSafetyCurve = slidingCircleMinimumSafetyCurve;
}
}