// 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.Collections.Generic;
using System.Linq;
using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.General.Results;
using Deltares.DamEngine.Data.Standard.Calculation;
using Deltares.DamEngine.Data.Standard.Logging;
using Deltares.MacroStability.CSharpWrapper;
using Deltares.MacroStability.CSharpWrapper.Output;
using MacroStabilityOutput = Deltares.MacroStability.CSharpWrapper.Output.MacroStabilityOutput;
using Point2D = Deltares.DamEngine.Data.Geometry.Point2D;
namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo;
///
/// Fills the engine results from the MacroStabilityWrapper
///
public class FillEngineFromMacroStabilityWrapperOutput
{
///
/// Fills the engine data with results.
///
/// The kernel output.
/// The macro stability output.
/// The log messages.
///
public static void FillEngineDataWithResults(MacroStabilityOutput kernelOutput,
MacroStabilityInwards.MacroStabilityOutput macroStabilityOutput, out List logMessages)
{
logMessages = null;
macroStabilityOutput.CalculationResult = ConversionHelper.ConvertToDamResultType(kernelOutput.ResultType);
if (kernelOutput.StabilityOutput != null)
{
var outputItem = new MacroStabilityOutputItem
{
CalculationResult = ConversionHelper.ConvertToDamResultType(kernelOutput.ResultType),
SafetyFactor = kernelOutput.StabilityOutput.SafetyFactor,
StabilityModelType = ConversionHelper.ConvertToMStabModelType(kernelOutput.StabilityOutput.ModelOptionType),
BishopCalculationCircle = new BishopCalculationCircle(),
UpliftVanCalculationGrid = new MacroStability.CSharpWrapper.UpliftVanCalculationGrid()
};
if (outputItem.StabilityModelType == MStabModelType.Bishop)
{
var slidingCircleMinimumSafetyCurve = (SlidingCircleMinimumSafetyCurve) kernelOutput.StabilityOutput.MinimumSafetyCurve;
FillBishopSlipCircle(slidingCircleMinimumSafetyCurve, outputItem);
}
if (outputItem.StabilityModelType == MStabModelType.UpliftVan)
{
var dualSlidingCircleMinimumSafetyCurve = (DualSlidingCircleMinimumSafetyCurve) kernelOutput.StabilityOutput.MinimumSafetyCurve;
FillUpliftVanDualSlipCircle(dualSlidingCircleMinimumSafetyCurve, outputItem);
}
if (macroStabilityOutput.CalculationResult == CalculationResult.Succeeded)
{
if (outputItem.StabilityModelType == MStabModelType.Bishop || outputItem.StabilityModelType == MStabModelType.BishopUpliftVan)
{
var bishopPreprocessingOutput = (BishopPreprocessingOutput) kernelOutput.PreprocessingOutputBase;
outputItem.BishopCalculationCircle = bishopPreprocessingOutput.BishopCalculationCircle;
}
if (outputItem.StabilityModelType == MStabModelType.UpliftVan || outputItem.StabilityModelType == MStabModelType.BishopUpliftVan)
{
var upliftVanPreprocessingOutput = (UpliftVanPreprocessingOutput) kernelOutput.PreprocessingOutputBase;
outputItem.UpliftVanCalculationGrid = upliftVanPreprocessingOutput.UpliftVanCalculationGrid;
}
}
if (outputItem.StabilityModelType == MStabModelType.Bishop ||
outputItem.StabilityModelType == MStabModelType.UpliftVan)
{
MinimumSafetyCurveBase minimumSafetyCurveBase = kernelOutput.StabilityOutput.MinimumSafetyCurve;
FillSlices(minimumSafetyCurveBase, outputItem);
if (outputItem.CalculationResult == CalculationResult.Succeeded && minimumSafetyCurveBase != null &&
minimumSafetyCurveBase.Slices != null && minimumSafetyCurveBase.Slices.Any())
{
outputItem.CircleSurfacePointRightXCoordinate = minimumSafetyCurveBase.Slices.Last().TopRightPoint.X;
}
}
macroStabilityOutput.StabilityOutputItems.Add(outputItem);
if (kernelOutput.StabilityOutput.Messages != null && kernelOutput.StabilityOutput.Messages.Any())
{
logMessages = new List();
foreach (Message stabilityOutputMessage in kernelOutput.StabilityOutput.Messages)
{
var logMessage = new LogMessage
{
Message = stabilityOutputMessage.Content,
MessageType = ConversionHelper.ConvertKernelLogMessageTypeToLogMessageType(
stabilityOutputMessage.MessageType)
};
logMessages.Add(logMessage);
}
}
}
}
private static void FillUpliftVanDualSlipCircle(DualSlidingCircleMinimumSafetyCurve dualSlidingCircleMinimumSafetyCurve,
MacroStabilityOutputItem outputItem)
{
if (dualSlidingCircleMinimumSafetyCurve != null && dualSlidingCircleMinimumSafetyCurve.ActiveCircleCenter != null && dualSlidingCircleMinimumSafetyCurve.PassiveCircleCenter != null)
{
outputItem.ActiveCenterPoint =
new Point2D(dualSlidingCircleMinimumSafetyCurve.ActiveCircleCenter.X, dualSlidingCircleMinimumSafetyCurve.ActiveCircleCenter.Z);
outputItem.ActiveCenterPointRadius = dualSlidingCircleMinimumSafetyCurve.ActiveCircleRadius;
outputItem.PassiveCenterPoint =
new Point2D(dualSlidingCircleMinimumSafetyCurve.PassiveCircleCenter.X, dualSlidingCircleMinimumSafetyCurve.PassiveCircleCenter.Z);
outputItem.PassiveCenterPointRadius = dualSlidingCircleMinimumSafetyCurve.PassiveCircleRadius;
}
}
private static void FillBishopSlipCircle(SlidingCircleMinimumSafetyCurve slidingCircleMinimumSafetyCurve, MacroStabilityOutputItem outputItem)
{
if (slidingCircleMinimumSafetyCurve != null && slidingCircleMinimumSafetyCurve.Center != null)
{
outputItem.ActiveCenterPoint = new Point2D(slidingCircleMinimumSafetyCurve.Center.X, slidingCircleMinimumSafetyCurve.Center.Z);
outputItem.ActiveCenterPointRadius = slidingCircleMinimumSafetyCurve.Radius;
}
}
private static void FillSlices(MinimumSafetyCurveBase minimumSafetyCurveBase, MacroStabilityOutputItem outputItem)
{
if (minimumSafetyCurveBase != null && minimumSafetyCurveBase.Slices != null)
{
outputItem.ResultSlices = new List();
foreach (Slice slice in minimumSafetyCurveBase.Slices)
{
var resultSlice = new StabilityResultSlice();
resultSlice.TopLeftPoint = new Point2D(slice.TopLeftPoint.X, slice.TopLeftPoint.Z);
resultSlice.TopRightPoint = new Point2D(slice.TopRightPoint.X, slice.TopRightPoint.Z);
resultSlice.BottomLeftPoint = new Point2D(slice.BottomLeftPoint.X, slice.BottomLeftPoint.Z);
resultSlice.BottomRightPoint = new Point2D(slice.BottomRightPoint.X, slice.BottomRightPoint.Z);
resultSlice.Name = slice.Name;
resultSlice.Width = slice.Width;
resultSlice.ArcLength = slice.ArcLength;
resultSlice.TopAngle = slice.TopAngle;
resultSlice.BottomAngle = slice.BottomAngle;
resultSlice.CohesionInput = slice.CohesionInput;
resultSlice.CohesionOutput = slice.CohesionOutput;
resultSlice.FrictionAngleInput = slice.FrictionAngleInput;
resultSlice.FrictionAngleOutput = slice.FrictionAngleOutput;
resultSlice.YieldStress = slice.YieldStress;
resultSlice.OCR = slice.OCR;
resultSlice.POP = slice.POP;
resultSlice.DegreeOfConsolidationPorePressure = slice.DegreeOfConsolidationPorePressure;
resultSlice.PorePressureDueToDegreeOfConsolidationLoad = slice.PorePressureDueToDegreeOfConsolidationLoad;
resultSlice.DilatancyInput = slice.DilatancyInput;
resultSlice.ExternalLoad = slice.ExternalLoad;
resultSlice.HydrostaticPorePressure = slice.HydrostaticPorePressure;
resultSlice.LeftForce = slice.LeftForce;
resultSlice.LeftForceAngle = slice.LeftForceAngle;
resultSlice.LeftForceY = slice.LeftForceY;
resultSlice.RightForce = slice.RightForce;
resultSlice.RightForceAngle = slice.RightForceAngle;
resultSlice.RightForceY = slice.RightForceY;
resultSlice.LoadStress = slice.LoadStress;
resultSlice.NormalStress = slice.NormalStress;
resultSlice.PorePressure = slice.PorePressure;
resultSlice.HorizontalPorePressure = slice.HorizontalPorePressure;
resultSlice.VerticalPorePressure = slice.VerticalPorePressure;
resultSlice.PiezometricPorePressure = slice.PiezometricPorePressure;
resultSlice.EffectiveStress = slice.EffectiveStress;
resultSlice.ExcessPorePressure = slice.ExcessPorePressure;
resultSlice.ShearStressInput = slice.ShearStressInput;
resultSlice.ShearStressOutput = slice.ShearStressOutput;
resultSlice.SoilStress = slice.SoilStress;
resultSlice.TotalPorePressure = slice.TotalPorePressure;
resultSlice.TotalStress = slice.TotalStress;
resultSlice.Weight = slice.Weight;
resultSlice.SuInput = slice.SuInput;
resultSlice.SuOutput = slice.SuOutput;
resultSlice.ShearStrengthModel = ConversionHelper.ConvertToDamShearStrengthModel(slice.ShearStrengthModelType);
resultSlice.HorizontalSoilQuakeStress = slice.HorizontalSoilQuakeStress;
resultSlice.StrengthIncreaseExponent = slice.StrengthIncreaseExponent;
resultSlice.UpliftFactor = slice.UpliftFactor;
resultSlice.VerticalSoilQuakeStress = slice.VerticalSoilQuakeStress;
resultSlice.WaterQuakeStress = slice.WaterQuakeStress;
resultSlice.UpliftReductionFactor = slice.UpliftReductionFactor;
resultSlice.RatioCuPc = slice.RatioCuPc;
resultSlice.ResultantForce = slice.ResultantForce;
resultSlice.ResultantMoment = slice.ResultantMoment;
resultSlice.ResultantAngle = slice.ResultantAngle;
outputItem.ResultSlices.Add(resultSlice);
}
}
}
}