// Copyright (C) Stichting Deltares 2024. All rights reserved. // // This file is part of the application DAM - UI. // // DAM - UI is free software: you can redistribute it and/or modify // it under the terms of the GNU 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 General Public License for more details. // // You should have received a copy of the GNU 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 System.IO; using System.Linq; using Deltares.DamEngine.Io.XmlOutput; using Deltares.Geometry; using Deltares.Geotechnics.GeotechnicalGeometry; using Deltares.Geotechnics.Soils; using Deltares.Geotechnics.SurfaceLines; using Deltares.Mathematics; using Deltares.Standard; using Deltares.Standard.EventPublisher; using Deltares.Standard.Logging; using SurfaceLine = Deltares.DamEngine.Io.XmlOutput.SurfaceLine; namespace Deltares.Dam.Data.DamEngineIo; /// /// Exception class for FillDamUiFromXmlOutput /// public class FillDamUiFromXmlOutputException : Exception { public FillDamUiFromXmlOutputException(string message) : base(message) {} } /// /// Class to support the conversion of XmlOutput (as provided by the Engine) to DamUI objects. /// public class FillDamUiFromXmlOutput { /// /// Adds the output to dam project data. /// Precondition is that dam project data is filled and contains all relevant data that is referred to in the Output. /// /// The dam project data. /// The output. /// public static DamProjectData AddOutputToDamProjectData(DamProjectData damProjectData, Output output) { if (output?.Results?.CalculationResults != null) { DataEventPublisher.InvokeWithoutPublishingEvents(() => { CreateDesignResultsFromOutput(output, damProjectData); } ); } // Transfer calculation messages if (output?.Results?.CalculationMessages != null) { damProjectData.CalculationMessages = new List(); for (var i = 0; i < output.Results.CalculationMessages.Length; i++) { Message validationResult = output.Results.CalculationMessages[i]; var logMessage = new LogMessage { MessageType = ConversionHelper.ConvertToMessageType(validationResult.MessageType), Subject = null, Message = validationResult.Message1 }; damProjectData.CalculationMessages.Add(logMessage); } } // Transfer output time series if (output != null && output.Results != null && output.Results.OperationalOutputTimeSeries != null) { damProjectData.OutputTimeSerieCollection = new TimeSerieCollection(); TransferOutputTimeSeries(output.Results.OperationalOutputTimeSeries, damProjectData.OutputTimeSerieCollection); if (output.Results.OperationalStaticData is { StabilityModel: OperationalStaticDataStabilityModel.Bishop }) { TransferOutputTimeSeries(output.Results.OperationalOutputTimeSeries, damProjectData.OutputTimeSerieCollection, TimeSerieParameters.BishopCircleCentreX.ToString()); TransferOutputTimeSeries(output.Results.OperationalOutputTimeSeries, damProjectData.OutputTimeSerieCollection, TimeSerieParameters.BishopCircleCentreZ.ToString()); TransferOutputTimeSeries(output.Results.OperationalOutputTimeSeries, damProjectData.OutputTimeSerieCollection, TimeSerieParameters.BishopCircleRadius.ToString()); } } damProjectData.TransferOutputTimeSerieToLocationJobs(); return damProjectData; } private static void TransferOutputTimeSeries(TimeSerieOutput[] outputTimeSeries, TimeSerieCollection outputTimeSerieCollection, string parameterId = "") { foreach (TimeSerieOutput outputTimeSerie in outputTimeSeries) { TimeSerie timeSerie = outputTimeSerieCollection.AddNewSeries(outputTimeSerie.LocationId); timeSerie.ParameterId = parameterId == "" ? outputTimeSerie.ParameterId : parameterId; timeSerie.ForecastDateTime = outputTimeSerie.ForecastDateTime; timeSerie.StartDateTime = outputTimeSerie.StartDateTime; timeSerie.EndDateTime = outputTimeSerie.EndDateTime; timeSerie.MissVal = outputTimeSerie.MissVal; timeSerie.Units = outputTimeSerie.Units; for (var i = 0; i < outputTimeSerie.Entries.TimeSerieEntryOutput.Length; i++) { TimeSerieOutputEntriesTimeSerieEntryOutput entry = outputTimeSerie.Entries.TimeSerieEntryOutput[i]; var timeSerieEntry = new TimeSerieEntry { DateTime = entry.DateTime }; if (parameterId == "") { timeSerieEntry.Value = entry.Value; } if (parameterId == TimeSerieParameters.BishopCircleCentreX.ToString()) { timeSerieEntry.Value = entry.BishopCalculatedSlipPlane is { Center: not null } ? entry.BishopCalculatedSlipPlane.Center.X : double.NaN; } if (parameterId == TimeSerieParameters.BishopCircleCentreZ.ToString()) { timeSerieEntry.Value = entry.BishopCalculatedSlipPlane is { Center: not null } ? entry.BishopCalculatedSlipPlane.Center.Z : double.NaN; } if (parameterId == TimeSerieParameters.BishopCircleRadius.ToString()) { timeSerieEntry.Value = entry.BishopCalculatedSlipPlane?.Radius ?? double.NaN; } timeSerie.Entries.Add(timeSerieEntry); } } } private static void CreateDesignResultsFromOutput(Output output, DamProjectData damProjectData) { if (damProjectData.WaterBoard.Dikes[0] != null) { // Design results damProjectData.DesignCalculations = new List(); for (var i = 0; i < output.Results.CalculationResults.Length; i++) { DesignResult designResult = output.Results.CalculationResults[i]; if (string.IsNullOrEmpty(designResult.BaseFileName)) { designResult.BaseFileName = "Loc(" + designResult.LocationName + ")_Prof(" + designResult.ProfileName + ")_Scen(" + designResult.ScenarioName + ")"; } var desResult = new CsvExportData(designResult.LocationName, designResult.ScenarioName) { DamFailureMechanismeCalculation = damProjectData.DamProjectCalculationSpecification.CurrentSpecification, // vanuit invoer AnalysisType = DamProjectCalculationSpecification.SelectedAnalysisType, //is vanuit invoer DikeName = damProjectData.WaterBoard.Dikes[0].Name, // is de enige voor nu CalculationResult = ConversionHelper.ConvertToCalculationResult(designResult.CalculationResult), BaseFileName = designResult.BaseFileName, CalculationSubDir = designResult.CalculationSubDir, ProfileName = designResult.ProfileName }; desResult.CalculationResult = ConversionHelper.ConvertToCalculationResult(designResult.CalculationResult); Scenario scenario = GetScenarioByName(damProjectData, designResult.LocationName, designResult.ScenarioName); desResult.Scenario = scenario; SoilProfile1D soilProfile = GetSoilProfileByName(damProjectData, designResult.ProfileName); if (soilProfile == null) { desResult.SoilGeometry2DName = designResult.ProfileName; } else { desResult.SoilProfile = soilProfile; } if (designResult.PipingDesignResults != null) { CreateDesignResultsPipingOutput(designResult, desResult); } if (designResult.StabilityDesignResults != null) { CreateDesignResultsStabilityOutput(designResult, desResult); } int index = output.Results.CalculationResults.Where(y => y.LocationName == designResult.LocationName).ToList().IndexOf(designResult); if (desResult.Scenario != null) { desResult.LocationScenarioCount = scenario.Location.Scenarios.Count; desResult.ScenarioIndex = index; desResult.Scenario.CalculationResult = desResult.CalculationResult; desResult.Scenario.CalculationResults.Add(desResult); } damProjectData.DesignCalculations.Add(desResult); } } } private static void CreateDesignResultsPipingOutput(DesignResult designResult, CsvExportData desResult) { desResult.ResultMessage = designResult.PipingDesignResults.ResultMessage; if (designResult.PipingDesignResults.RedesignedSurfaceLine != null) { desResult.RedesignedSurfaceLine2 = new SurfaceLine2(); SurfaceLine2 surfaceLine = ConvertXmlSurfaceLineToSurfaceLine2(designResult.PipingDesignResults.RedesignedSurfaceLine); desResult.RedesignedSurfaceLine2 = surfaceLine; } if (designResult.PipingDesignResults.UpliftFactorSpecified) { desResult.UpliftFactor = designResult.PipingDesignResults.UpliftFactor; } if (designResult.PipingDesignResults.HeaveFactorSpecified) { desResult.HeaveFactor = designResult.PipingDesignResults.HeaveFactor; } if (designResult.PipingDesignResults.BlighFactorSpecified) { desResult.BlighPipingFactor = designResult.PipingDesignResults.BlighFactor; } if (designResult.PipingDesignResults.BlighHcriticalSpecified) { desResult.BlighHCritical = designResult.PipingDesignResults.BlighHcritical; } if (designResult.PipingDesignResults.Wti2017BackwardErosionFactorSpecified) { desResult.Wti2017BackwardErosionSafetyFactor = designResult.PipingDesignResults.Wti2017BackwardErosionFactor; } if (designResult.PipingDesignResults.Wti2017BackwardErosionHcriticalSpecified) { desResult.Wti2017BackwardErosionHcritical = designResult.PipingDesignResults.Wti2017BackwardErosionHcritical; } if (designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiCSpecified) { desResult.Wti2017BackwardErosionDeltaPhiC = designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiC; } if (designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiReducedSpecified) { desResult.Wti2017BackwardErosionDeltaPhiReduced = designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiReduced; } if (designResult.PipingDesignResults.Wti2017UpliftFactorSpecified) { desResult.Wti2017UpliftSafetyFactor = designResult.PipingDesignResults.Wti2017UpliftFactor; } if (designResult.PipingDesignResults.Wti2017UpliftHcriticalSpecified) { desResult.Wti2017UpliftHcritical = designResult.PipingDesignResults.Wti2017UpliftHcritical; } if (designResult.PipingDesignResults.Wti2017DeltaPhiCuSpecified) { desResult.Wti2017UpliftDeltaPhiC = designResult.PipingDesignResults.Wti2017DeltaPhiCu; } if (designResult.PipingDesignResults.Wti2017HeaveFactorSpecified) { desResult.Wti2017HeaveSafetyFactor = designResult.PipingDesignResults.Wti2017HeaveFactor; } if (designResult.PipingDesignResults.Wti2017HeaveHcriticalSpecified) { desResult.Wti2017HeaveHcritical = designResult.PipingDesignResults.Wti2017HeaveHcritical; } if (designResult.PipingDesignResults.Wti2017GradientSpecified) { desResult.Wti2017Gradient = designResult.PipingDesignResults.Wti2017Gradient; } if (designResult.PipingDesignResults.Wti2017FactorOverallSpecified) { desResult.Wti2017SafetyFactorOverall = designResult.PipingDesignResults.Wti2017FactorOverall; } if (designResult.PipingDesignResults.Wti2017HcriticalOverallSpecified) { desResult.Wti2017HcriticalOverall = designResult.PipingDesignResults.Wti2017HcriticalOverall; } if (designResult.PipingDesignResults.Wti2017EffectiveStressSpecified) { desResult.Wti2017EffectiveStress = designResult.PipingDesignResults.Wti2017EffectiveStress; } if (designResult.PipingDesignResults.Wti2017CCreepSpecified) { desResult.Wti2017CCreep = designResult.PipingDesignResults.Wti2017CCreep; } if (designResult.PipingDesignResults.ExitPointXSpecified) { desResult.LocalPipingExitPointX = designResult.PipingDesignResults.ExitPointX; } if (designResult.PipingDesignResults.UpliftSituation != null) { DamEngine.Io.XmlOutput.UpliftSituation uplift = designResult.PipingDesignResults.UpliftSituation; desResult.IsUplift = uplift.IsUplift; if (desResult.IsUplift.Value) { desResult.IsUplift = uplift.IsUplift; desResult.Pl3MinUplift = uplift.Pl3MinUplift; desResult.Pl3HeadAdjusted = uplift.Pl3HeadAdjusted; desResult.Pl3LocalLocationXMinUplift = uplift.Pl3LocationXMinUplift; desResult.Pl4MinUplift = uplift.Pl4MinUplift; desResult.Pl4HeadAdjusted = uplift.Pl4HeadAdjusted; desResult.Pl4LocalLocationXMinUplift = uplift.Pl4LocationXMinUplift; } else { ResetUpliftValues(desResult); } } else { ResetUpliftValues(desResult); } if (string.IsNullOrEmpty(desResult.CalculationSubDir)) { desResult.CalculationSubDir = Path.Combine("Piping", desResult.PipingModel.ToString()); } if (string.IsNullOrEmpty(desResult.BaseFileName)) { desResult.BaseFileName = "Loc(" + designResult.LocationName + ")_Prof(" + designResult.ProfileName + ")_Scen(" + designResult.ScenarioName + ")"; } desResult.CreateResultsFileForSurfaceLineAndProfile(desResult.PipingResultFile); } private static Scenario GetScenarioByName(DamProjectData damProjectData, string locationName, string scenarioName) { List locations = damProjectData.Locations; foreach (Location location in locations) { if (location.Name == locationName) { foreach (Scenario scenario in location.Scenarios) { if (scenario.LocationScenarioID == scenarioName) { return scenario; } } } } return null; } private static SoilProfile1D GetSoilProfileByName(DamProjectData damProjectData, string profileName) { IList soilProfiles1D = damProjectData.WaterBoard.Dikes[0].SoilProfiles; foreach (SoilProfile1D soilProfile1D in soilProfiles1D) { if (soilProfile1D.Name == profileName) { return soilProfile1D; } } return null; } private static SurfaceLine2 ConvertXmlSurfaceLineToSurfaceLine2(SurfaceLine inputSurfaceLine) { var surfaceLine = new SurfaceLine2 { Name = inputSurfaceLine.Name }; surfaceLine.CharacteristicPoints.Geometry = surfaceLine.Geometry; AddPointsToSurfaceLine(inputSurfaceLine, surfaceLine); return surfaceLine; } private static void AddPointsToSurfaceLine(SurfaceLine inputSurfaceLine, SurfaceLine2 surfaceLine) { surfaceLine.Geometry = new LocalizedGeometryPointString(); for (var j = 0; j < inputSurfaceLine.Points.Length; j++) { SurfaceLinePoint inputPoint = inputSurfaceLine.Points[j]; var geometryPoint = new GeometryPoint { X = inputPoint.X, Y = 0.0, Z = inputPoint.Z }; surfaceLine.AddCharacteristicPoint(geometryPoint, ConversionHelper.ConvertToDamPointType(inputPoint.PointType)); } } private static void CreateDesignResultsStabilityOutput(DesignResult designResult, CsvExportData desResult) { desResult.ResultMessage = designResult.StabilityDesignResults.ResultMessage; if (designResult.StabilityDesignResults.RedesignedSurfaceLine != null) { SurfaceLine2 surfaceLine = ConvertXmlSurfaceLineToSurfaceLine2(designResult.StabilityDesignResults.RedesignedSurfaceLine); desResult.RedesignedSurfaceLine2 = surfaceLine; } if (designResult.StabilityDesignResults.SafetyFactorSpecified) { desResult.StabilitySafetyFactor = designResult.StabilityDesignResults.SafetyFactor; } if (designResult.StabilityDesignResults.NumberOfIterationsSpecified) { desResult.NumberOfIterations = designResult.StabilityDesignResults.NumberOfIterations; } if (designResult.StabilityDesignResults.StabilityModelTypeSpecified) { desResult.StabilityModel = ConversionHelper.ConvertToStabilityModelType(designResult.StabilityDesignResults.StabilityModelType); } if (designResult.StabilityDesignResults.UpliftSituation != null) { CreateDesignUpliftSituationResults(designResult, desResult); } else { ResetUpliftValues(desResult); } if (designResult.StabilityDesignResults.SlipCircleDefinition != null) { CreateSlipPlaneDefinitionResults(designResult, desResult); } if (string.IsNullOrEmpty(desResult.CalculationSubDir) && (desResult.CalculationResult != CalculationResult.RunFailed) && (desResult.CalculationResult != CalculationResult.UnexpectedError)) { throw new FillDamUiFromXmlOutputException(nameof(desResult.CalculationSubDir) + " is null or empty."); } if (string.IsNullOrEmpty(desResult.BaseFileName)) { throw new FillDamUiFromXmlOutputException(nameof(desResult.BaseFileName) + " is null or empty."); } if ((desResult.CalculationResult != CalculationResult.RunFailed) && (desResult.CalculationResult != CalculationResult.UnexpectedError && designResult.StabilityDesignResults.StabilityModelType != DesignResultStabilityDesignResultsStabilityModelType.BishopUpliftVan)) { desResult.CreateResultsFileForSurfaceLineAndProfile(desResult.GetDesignResultFile()); } } private static void CreateSlipPlaneDefinitionResults(DesignResult designResult, CsvExportData desResult) { bool isBishop = designResult.StabilityDesignResults.StabilityModelType == DesignResultStabilityDesignResultsStabilityModelType.Bishop; bool isUpliftVan = designResult.StabilityDesignResults.StabilityModelType == DesignResultStabilityDesignResultsStabilityModelType.UpliftVan; if (designResult.StabilityDesignResults.StabilityModelType == DesignResultStabilityDesignResultsStabilityModelType.BishopUpliftVan) { isBishop = designResult.StabilityDesignResults.SlipCircleDefinition is SlidingCircleMinimumSafetyCurveType; isUpliftVan = designResult.StabilityDesignResults.SlipCircleDefinition is DualSlidingCircleMinimumSafetyCurveType; } if (isBishop) { var singleSlipCircleDefinition = (SlidingCircleMinimumSafetyCurveType) designResult.StabilityDesignResults.SlipCircleDefinition; if (singleSlipCircleDefinition.Center != null) { desResult.ActiveCenterPointX = singleSlipCircleDefinition.Center.X; desResult.ActiveCenterPointZ = singleSlipCircleDefinition.Center.Z; desResult.ActiveCenterPointRadius = singleSlipCircleDefinition.Radius; } } if (isUpliftVan) { var dualSlipCircleDefinition = (DualSlidingCircleMinimumSafetyCurveType) designResult.StabilityDesignResults.SlipCircleDefinition; if (dualSlipCircleDefinition.ActiveCircleCenter != null) { desResult.ActiveCenterPointX = dualSlipCircleDefinition.ActiveCircleCenter.X; desResult.ActiveCenterPointZ = dualSlipCircleDefinition.ActiveCircleCenter.Z; desResult.ActiveCenterPointRadius = dualSlipCircleDefinition.ActiveCircleRadius; } if (dualSlipCircleDefinition.PassiveCircleCenter != null) { desResult.PassiveCenterPointX = dualSlipCircleDefinition.PassiveCircleCenter.X; desResult.PassiveCenterPointZ = dualSlipCircleDefinition.PassiveCircleCenter.Z; desResult.PassiveCenterPointRadius = dualSlipCircleDefinition.PassiveCircleRadius; } } if (designResult.StabilityDesignResults.StabilityModelType is DesignResultStabilityDesignResultsStabilityModelType.Bishop or DesignResultStabilityDesignResultsStabilityModelType.UpliftVan or DesignResultStabilityDesignResultsStabilityModelType.BishopUpliftVan) { if (designResult.StabilityDesignResults.SlipCircleDefinition.Slices != null) { desResult.ResultSlices = new List(); foreach (MinimumSafetyCurveBaseTypeSlice slice in designResult.StabilityDesignResults.SlipCircleDefinition.Slices) { var resultSlice = new StabilityResultSlice { TopLeftPoint = new Point2D(slice.TopLeftPoint.X, slice.TopLeftPoint.Z), TopRightPoint = new Point2D(slice.TopRightPoint.X, slice.TopRightPoint.Z), BottomLeftPoint = new Point2D(slice.BottomLeftPoint.X, slice.BottomLeftPoint.Z), BottomRightPoint = new Point2D(slice.BottomRightPoint.X, slice.BottomRightPoint.Z) }; desResult.ResultSlices.Add(resultSlice); } } } } private static void CreateDesignUpliftSituationResults(DesignResult designResult, CsvExportData desResult) { DamEngine.Io.XmlOutput.UpliftSituation uplift = designResult.StabilityDesignResults.UpliftSituation; desResult.IsUplift = uplift.IsUplift; if (desResult.IsUplift.Value) { desResult.Pl3MinUplift = uplift.Pl3MinUplift; desResult.Pl3HeadAdjusted = uplift.Pl3HeadAdjusted; desResult.Pl3LocalLocationXMinUplift = uplift.Pl3LocationXMinUplift; desResult.Pl4MinUplift = uplift.Pl4MinUplift; desResult.Pl4HeadAdjusted = uplift.Pl4HeadAdjusted; desResult.Pl4LocalLocationXMinUplift = uplift.Pl4LocationXMinUplift; } else { ResetUpliftValues(desResult); } } private static void ResetUpliftValues(CsvExportData desResult) { desResult.Pl3MinUplift = null; desResult.Pl3HeadAdjusted = null; desResult.Pl3LocalLocationXMinUplift = null; desResult.Pl4MinUplift = null; desResult.Pl4HeadAdjusted = null; desResult.Pl4LocalLocationXMinUplift = null; } }