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