// 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 Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.General.Results;
using Deltares.DamEngine.Data.General.TimeSeries;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard.Logging;
using Deltares.DamEngine.Io.XmlOutput;
using DesignResult = Deltares.DamEngine.Io.XmlOutput.DesignResult;
using TimeSerie = Deltares.DamEngine.Io.XmlOutput.TimeSerieOutput;
using UpliftSituation = Deltares.DamEngine.Data.General.UpliftSituation;
namespace Deltares.DamEngine.Interface;
///
/// Class to fill the output xml based on the results in DamProjectData
///
public class FillXmlOutputFromDam
{
///
/// Creates the output.
///
/// The dam project data.
///
public static Output CreateOutput(DamProjectData damProjectData)
{
// Echo of the input
var output = new Output
{
ValidationResults = new Message[0],
// Results
Results = new OutputResults
{
// Calculation messages
CalculationMessages = new Message[damProjectData.CalculationMessages.Count]
}
};
CreateCalculationMessages(damProjectData, output);
CreateDesignResultsOutput(damProjectData, output);
CreateOperationalResultsOutput(damProjectData, output);
return output;
}
private static void CreateDesignResultsOutput(DamProjectData damProjectData, Output output)
{
// Design results
List designResults = damProjectData.DesignCalculations;
if (designResults != null && designResults.Count > 0)
{
output.Results.CalculationResults = new DesignResult[designResults.Count];
var designResultCount = 0;
foreach (Data.General.Results.DesignResult designResult in designResults)
{
var desResult = new DesignResult
{
BaseFileName = designResult.BaseFileName,
CalculationSubDir = designResult.CalculationSubDir,
LocationName = designResult.LocationName,
ScenarioName = designResult.ScenarioName,
ProfileName = designResult.ProfileName,
CalculationResult = ConversionHelper.ConvertToOutputCalculationResult(designResult.CalculationResult)
};
if (designResult.PipingDesignResults != null)
{
CreateDesignResultsPipingOutput(desResult, designResult);
}
if (designResult.StabilityDesignResults != null)
{
CreateDesignResultsStabilityOutput(desResult, designResult);
}
output.Results.CalculationResults[designResultCount] = desResult;
designResultCount++;
}
}
}
private static void CreateCalculationMessages(DamProjectData damProjectData, Output output)
{
List calculationMessages = damProjectData.CalculationMessages;
if (calculationMessages != null)
{
output.Results.CalculationMessages = new Message[calculationMessages.Count];
for (var i = 0; i < calculationMessages.Count; i++)
{
var message = new Message
{
MessageType = ConversionHelper.ConvertToInputMessageType(calculationMessages[i].MessageType)
};
if (calculationMessages[i].Subject != null)
{
message.Message1 = calculationMessages[i].Subject + ": " + calculationMessages[i].Message;
}
else
{
message.Message1 = calculationMessages[i].Message;
}
output.Results.CalculationMessages[i] = message;
}
}
}
private static void CreateDesignResultsPipingOutput(DesignResult desResult, Data.General.Results.DesignResult designResult)
{
desResult.PipingDesignResults = new DesignResultPipingDesignResults
{
ResultMessage = designResult.PipingDesignResults.ResultMessage
};
if (designResult.PipingDesignResults.RedesignedSurfaceLine != null)
{
desResult.PipingDesignResults.RedesignedSurfaceLine = new SurfaceLine
{
Name = designResult.PipingDesignResults.RedesignedSurfaceLine.Name,
Points = new SurfaceLinePoint[designResult.PipingDesignResults.RedesignedSurfaceLine.CharacteristicPoints.Count]
};
for (var j = 0; j < designResult.PipingDesignResults.RedesignedSurfaceLine.CharacteristicPoints.Count; j++)
{
CharacteristicPoint characteristicPoint = designResult.PipingDesignResults.RedesignedSurfaceLine.CharacteristicPoints[j];
var inputPoint = new SurfaceLinePoint
{
PointType = ConversionHelper.ConvertToInputPointType(characteristicPoint.CharacteristicPointType),
X = characteristicPoint.Point.X,
Z = characteristicPoint.Point.Z
};
desResult.PipingDesignResults.RedesignedSurfaceLine.Points[j] = inputPoint;
}
}
desResult.PipingDesignResults.UpliftFactorSpecified = designResult.PipingDesignResults.UpliftFactor.HasValue;
if (designResult.PipingDesignResults.UpliftFactor.HasValue)
{
desResult.PipingDesignResults.UpliftFactor = designResult.PipingDesignResults.UpliftFactor.Value;
}
desResult.PipingDesignResults.HeaveFactorSpecified = designResult.PipingDesignResults.HeaveFactor.HasValue;
if (designResult.PipingDesignResults.HeaveFactor.HasValue)
{
desResult.PipingDesignResults.HeaveFactor = designResult.PipingDesignResults.HeaveFactor.Value;
}
desResult.PipingDesignResults.BlighFactorSpecified = designResult.PipingDesignResults.BlighFactor.HasValue;
if (designResult.PipingDesignResults.BlighFactor.HasValue)
{
desResult.PipingDesignResults.BlighFactor = designResult.PipingDesignResults.BlighFactor.Value;
}
desResult.PipingDesignResults.BlighHcriticalSpecified = designResult.PipingDesignResults.BlighHcritical.HasValue;
if (designResult.PipingDesignResults.BlighHcritical.HasValue)
{
desResult.PipingDesignResults.BlighHcritical = designResult.PipingDesignResults.BlighHcritical.Value;
}
desResult.PipingDesignResults.Wti2017BackwardErosionFactorSpecified = designResult.PipingDesignResults.Wti2017BackwardErosionSafetyFactor.HasValue;
if (designResult.PipingDesignResults.Wti2017BackwardErosionSafetyFactor.HasValue)
{
desResult.PipingDesignResults.Wti2017BackwardErosionFactor = designResult.PipingDesignResults.Wti2017BackwardErosionSafetyFactor.Value;
}
desResult.PipingDesignResults.Wti2017BackwardErosionHcriticalSpecified = designResult.PipingDesignResults.Wti2017BackwardErosionHcritical.HasValue;
if (designResult.PipingDesignResults.Wti2017BackwardErosionHcritical.HasValue)
{
desResult.PipingDesignResults.Wti2017BackwardErosionHcritical = designResult.PipingDesignResults.Wti2017BackwardErosionHcritical.Value;
}
desResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiCSpecified = designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiC.HasValue;
if (designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiC.HasValue)
{
desResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiC = designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiC.Value;
}
desResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiReducedSpecified = designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiReduced.HasValue;
if (designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiReduced.HasValue)
{
desResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiReduced = designResult.PipingDesignResults.Wti2017BackwardErosionDeltaPhiReduced.Value;
}
desResult.PipingDesignResults.Wti2017UpliftFactorSpecified = designResult.PipingDesignResults.Wti2017UpliftSafetyFactor.HasValue;
if (designResult.PipingDesignResults.Wti2017UpliftSafetyFactor.HasValue)
{
desResult.PipingDesignResults.Wti2017UpliftFactor = designResult.PipingDesignResults.Wti2017UpliftSafetyFactor.Value;
}
desResult.PipingDesignResults.Wti2017UpliftHcriticalSpecified = designResult.PipingDesignResults.Wti2017UpliftHcritical.HasValue;
if (designResult.PipingDesignResults.Wti2017UpliftHcritical.HasValue)
{
desResult.PipingDesignResults.Wti2017UpliftHcritical = designResult.PipingDesignResults.Wti2017UpliftHcritical.Value;
}
desResult.PipingDesignResults.Wti2017DeltaPhiCuSpecified = designResult.PipingDesignResults.Wti2017UpliftDeltaPhiC.HasValue;
if (designResult.PipingDesignResults.Wti2017UpliftDeltaPhiC.HasValue)
{
desResult.PipingDesignResults.Wti2017DeltaPhiCu = designResult.PipingDesignResults.Wti2017UpliftDeltaPhiC.Value;
}
desResult.PipingDesignResults.Wti2017HeaveFactorSpecified = designResult.PipingDesignResults.Wti2017HeaveSafetyFactor.HasValue;
if (designResult.PipingDesignResults.Wti2017HeaveSafetyFactor.HasValue)
{
desResult.PipingDesignResults.Wti2017HeaveFactor = designResult.PipingDesignResults.Wti2017HeaveSafetyFactor.Value;
}
desResult.PipingDesignResults.Wti2017HeaveHcriticalSpecified = designResult.PipingDesignResults.Wti2017HeaveHcritical.HasValue;
if (designResult.PipingDesignResults.Wti2017HeaveHcritical.HasValue)
{
desResult.PipingDesignResults.Wti2017HeaveHcritical = designResult.PipingDesignResults.Wti2017HeaveHcritical.Value;
}
desResult.PipingDesignResults.Wti2017GradientSpecified = designResult.PipingDesignResults.Wti2017Gradient.HasValue;
if (designResult.PipingDesignResults.Wti2017Gradient.HasValue)
{
desResult.PipingDesignResults.Wti2017Gradient = designResult.PipingDesignResults.Wti2017Gradient.Value;
}
desResult.PipingDesignResults.Wti2017FactorOverallSpecified = designResult.PipingDesignResults.Wti2017SafetyFactorOverall.HasValue;
if (designResult.PipingDesignResults.Wti2017SafetyFactorOverall.HasValue)
{
desResult.PipingDesignResults.Wti2017FactorOverall = designResult.PipingDesignResults.Wti2017SafetyFactorOverall.Value;
}
desResult.PipingDesignResults.Wti2017HcriticalOverallSpecified = designResult.PipingDesignResults.Wti2017HcriticalOverall.HasValue;
if (designResult.PipingDesignResults.Wti2017HcriticalOverall.HasValue)
{
desResult.PipingDesignResults.Wti2017HcriticalOverall = designResult.PipingDesignResults.Wti2017HcriticalOverall.Value;
}
desResult.PipingDesignResults.ExitPointXSpecified = designResult.PipingDesignResults.LocalExitPointX.HasValue;
if (designResult.PipingDesignResults.LocalExitPointX.HasValue)
{
desResult.PipingDesignResults.ExitPointX = designResult.PipingDesignResults.LocalExitPointX.Value;
}
desResult.PipingDesignResults.Wti2017EffectiveStressSpecified = designResult.PipingDesignResults.EffectiveStress.HasValue;
if (designResult.PipingDesignResults.EffectiveStress.HasValue)
{
desResult.PipingDesignResults.Wti2017EffectiveStress = designResult.PipingDesignResults.EffectiveStress.Value;
}
desResult.PipingDesignResults.Wti2017CCreepSpecified = designResult.PipingDesignResults.CCreep.HasValue;
if (designResult.PipingDesignResults.CCreep.HasValue)
{
desResult.PipingDesignResults.Wti2017CCreep = designResult.PipingDesignResults.CCreep.Value;
}
if (designResult.PipingDesignResults.UpliftSituation.HasValue)
{
UpliftSituation uplift = designResult.PipingDesignResults.UpliftSituation.Value;
desResult.PipingDesignResults.UpliftSituation = new Io.XmlOutput.UpliftSituation
{
IsUplift = uplift.IsUplift,
Pl3MinUplift = uplift.Pl3MinUplift,
Pl3HeadAdjusted = uplift.Pl3HeadAdjusted,
Pl3LocationXMinUplift = uplift.Pl3LocationXMinUplift,
Pl4MinUplift = uplift.Pl4MinUplift,
Pl4HeadAdjusted = uplift.Pl4HeadAdjusted,
Pl4LocationXMinUplift = uplift.Pl4LocationXMinUplift
};
}
}
private static void CreateDesignResultsStabilityOutput(DesignResult desResult, Data.General.Results.DesignResult designResult)
{
desResult.StabilityDesignResults = new DesignResultStabilityDesignResults
{
ResultMessage = designResult.StabilityDesignResults.ResultMessage
};
if (designResult.StabilityDesignResults.UpliftSituation.HasValue)
{
UpliftSituation uplift = designResult.StabilityDesignResults.UpliftSituation.Value;
desResult.StabilityDesignResults.UpliftSituation = new Io.XmlOutput.UpliftSituation
{
IsUplift = uplift.IsUplift,
Pl3MinUplift = uplift.Pl3MinUplift,
Pl3HeadAdjusted = uplift.Pl3HeadAdjusted,
Pl3LocationXMinUplift = uplift.Pl3LocationXMinUplift,
Pl4MinUplift = uplift.Pl4MinUplift,
Pl4HeadAdjusted = uplift.Pl4HeadAdjusted,
Pl4LocationXMinUplift = uplift.Pl4LocationXMinUplift
};
}
if (designResult.StabilityDesignResults.RedesignedSurfaceLine != null)
{
desResult.StabilityDesignResults.RedesignedSurfaceLine = new SurfaceLine
{
Name = designResult.StabilityDesignResults.RedesignedSurfaceLine.Name,
Points = new SurfaceLinePoint[designResult.StabilityDesignResults.RedesignedSurfaceLine.CharacteristicPoints.Count]
};
for (var j = 0; j < designResult.StabilityDesignResults.RedesignedSurfaceLine.CharacteristicPoints.Count; j++)
{
CharacteristicPoint characteristicPoint = designResult.StabilityDesignResults.RedesignedSurfaceLine.CharacteristicPoints[j];
var inputPoint = new SurfaceLinePoint
{
PointType = ConversionHelper.ConvertToInputPointType(characteristicPoint.CharacteristicPointType),
X = characteristicPoint.Point.X,
Z = characteristicPoint.Point.Z
};
desResult.StabilityDesignResults.RedesignedSurfaceLine.Points[j] = inputPoint;
}
}
if (designResult.StabilityDesignResults != null)
{
bool isBishop = designResult.StabilityDesignResults.StabilityModelType == StabilityModelType.Bishop;
bool isUpliftVan = designResult.StabilityDesignResults.StabilityModelType == StabilityModelType.UpliftVan;
if (designResult.StabilityDesignResults.StabilityModelType == StabilityModelType.BishopUpliftVan)
{
isBishop = designResult.StabilityDesignResults.PassiveCenterPoint == null;
isUpliftVan = designResult.StabilityDesignResults.PassiveCenterPoint != null;
}
if (isBishop)
{
desResult.StabilityDesignResults.SlipCircleDefinition = new SlidingCircleMinimumSafetyCurveType();
var singleSlipCircleDefinition = (SlidingCircleMinimumSafetyCurveType) desResult.StabilityDesignResults.SlipCircleDefinition;
if (designResult.StabilityDesignResults.ActiveCenterPoint != null)
{
singleSlipCircleDefinition.Center = new Point2DType
{
X = designResult.StabilityDesignResults.ActiveCenterPoint.X,
Z = designResult.StabilityDesignResults.ActiveCenterPoint.Z
};
singleSlipCircleDefinition.Radius = designResult.StabilityDesignResults.ActiveCenterPointRadius;
}
}
if (isUpliftVan)
{
desResult.StabilityDesignResults.SlipCircleDefinition = new DualSlidingCircleMinimumSafetyCurveType();
var dualSlipCircleDefinition = (DualSlidingCircleMinimumSafetyCurveType) desResult.StabilityDesignResults.SlipCircleDefinition;
if (designResult.StabilityDesignResults.ActiveCenterPoint != null)
{
dualSlipCircleDefinition.ActiveCircleCenter = new Point2DType
{
X = designResult.StabilityDesignResults.ActiveCenterPoint.X,
Z = designResult.StabilityDesignResults.ActiveCenterPoint.Z
};
dualSlipCircleDefinition.ActiveCircleRadius = designResult.StabilityDesignResults.ActiveCenterPointRadius;
}
if (designResult.StabilityDesignResults.PassiveCenterPoint != null)
{
dualSlipCircleDefinition.PassiveCircleCenter = new Point2DType
{
X = designResult.StabilityDesignResults.PassiveCenterPoint.X,
Z = designResult.StabilityDesignResults.PassiveCenterPoint.Z
};
dualSlipCircleDefinition.PassiveCircleRadius = designResult.StabilityDesignResults.PassiveCenterPointRadius;
}
}
if (designResult.StabilityDesignResults.StabilityModelType is StabilityModelType.Bishop or StabilityModelType.UpliftVan or StabilityModelType.BishopUpliftVan)
{
if (designResult.StabilityDesignResults.ResultSlices != null &&
designResult.StabilityDesignResults.ResultSlices.Count > 0)
{
desResult.StabilityDesignResults.SlipCircleDefinition.Slices =
new MinimumSafetyCurveBaseTypeSlice[designResult.StabilityDesignResults.ResultSlices.Count];
var index = 0;
foreach (StabilityResultSlice slice in designResult.StabilityDesignResults.ResultSlices)
{
var resultSlice = new MinimumSafetyCurveBaseTypeSlice
{
TopLeftPoint = new Point2DType
{
X = slice.TopLeftPoint.X,
Z = slice.TopLeftPoint.Z
},
TopRightPoint = new Point2DType
{
X = slice.TopRightPoint.X,
Z = slice.TopRightPoint.Z
},
BottomLeftPoint =
new Point2DType
{
X = slice.BottomLeftPoint.X,
Z = slice.BottomLeftPoint.Z
},
BottomRightPoint = new Point2DType
{
X = slice.BottomRightPoint.X,
Z = slice.BottomRightPoint.Z
}
};
desResult.StabilityDesignResults.SlipCircleDefinition.Slices[index] = resultSlice;
index++;
}
}
}
}
desResult.StabilityDesignResults.SafetyFactorSpecified = designResult.StabilityDesignResults.SafetyFactor.HasValue;
if (designResult.StabilityDesignResults.SafetyFactor.HasValue)
{
desResult.StabilityDesignResults.SafetyFactor = designResult.StabilityDesignResults.SafetyFactor.Value;
}
desResult.StabilityDesignResults.NumberOfIterationsSpecified = designResult.StabilityDesignResults.NumberOfIterations.HasValue;
if (designResult.StabilityDesignResults.NumberOfIterations.HasValue)
{
desResult.StabilityDesignResults.NumberOfIterations = designResult.StabilityDesignResults.NumberOfIterations.Value;
}
desResult.StabilityDesignResults.StabilityModelTypeSpecified = designResult.StabilityDesignResults.StabilityModelType.HasValue;
if (designResult.StabilityDesignResults.StabilityModelType.HasValue)
{
desResult.StabilityDesignResults.StabilityModelType = ConversionHelper.ConvertToOutputStabilityModelType(designResult.StabilityDesignResults.StabilityModelType.Value);
}
}
private static void CreateOperationalResultsOutput(DamProjectData damProjectData, Output output)
{
if (damProjectData.DamProjectCalculationSpecification.CurrentSpecification is
{ FailureMechanismSystemType: FailureMechanismSystemType.StabilityInside or FailureMechanismSystemType.StabilityOutside })
{
output.Results.OperationalStaticData = new OperationalStaticData
{
FailureMechanismSystemType = ConversionHelper.ConvertToOutputOperationalFailureMechanismSystemType(
damProjectData.DamProjectCalculationSpecification.CurrentSpecification.FailureMechanismSystemType),
StabilityModel = ConversionHelper.ConvertToOutputOperationalStabilityModel(
damProjectData.DamProjectCalculationSpecification.CurrentSpecification.StabilityModelType)
};
}
CreateLocationResultsOutput(damProjectData, output);
}
private static void CreateLocationResultsOutput(DamProjectData damProjectData, Output output)
{
// Calculation results (per location)
//output.Results.CalculationResults.LocationResults = new CalculationResultsLocationResult[damProjectData.LocationJobs.Count];
if (damProjectData.OutputTimeSerieCollection != null)
{
output.Results.OperationalOutputTimeSeries = new TimeSerie[damProjectData.OutputTimeSerieCollection.Series.Count];
TransferOutputTimeSeries(damProjectData.OutputTimeSerieCollection, output.Results.OperationalOutputTimeSeries);
}
}
private static void TransferOutputTimeSeries(TimeSerieCollection outputTimeSerieCollection, TimeSerie[] outputTimeSeries)
{
var timeSerieIndex = 0;
foreach (Data.General.TimeSeries.TimeSerie damTimeSerie in outputTimeSerieCollection.Series)
{
var outputTimeSerie = new TimeSerie();
outputTimeSerie.Entries = new TimeSerieOutputEntries();
outputTimeSerie.Entries.TimeSerieEntryOutput = new TimeSerieOutputEntriesTimeSerieEntryOutput[damTimeSerie.Entries.Count];
outputTimeSerie.LocationId = damTimeSerie.LocationId;
outputTimeSerie.ParameterId = damTimeSerie.ParameterId;
outputTimeSerie.ForecastDateTime = damTimeSerie.ForecastDateTime;
outputTimeSerie.StartDateTime = damTimeSerie.StartDateTime;
outputTimeSerie.EndDateTime = damTimeSerie.EndDateTime;
outputTimeSerie.MissVal = damTimeSerie.MissVal;
outputTimeSerie.Units = damTimeSerie.Units;
var timeSerieEntryIndex = 0;
foreach (TimeSerieEntry timestepEntry in damTimeSerie.Entries)
{
var timeStep = new TimeSerieOutputEntriesTimeSerieEntryOutput
{
DateTime = timestepEntry.DateTime,
Value = timestepEntry.Value
};
if (timestepEntry.BishopCircleCentreX.HasValue && timestepEntry.BishopCircleCentreZ.HasValue && timestepEntry.BishopCircleRadius.HasValue)
{
timeStep.BishopCalculatedSlipPlane = new BishopCalculatedSlipPlaneType
{
SafetyFactor = timestepEntry.Value,
Center = new Point2DType
{
X = (double) timestepEntry.BishopCircleCentreX,
Z = (double) timestepEntry.BishopCircleCentreZ
},
Radius = (double) timestepEntry.BishopCircleRadius
};
}
outputTimeSerie.Entries.TimeSerieEntryOutput[timeSerieEntryIndex] = timeStep;
timeSerieEntryIndex++;
}
outputTimeSeries[timeSerieIndex] = outputTimeSerie;
timeSerieIndex++;
}
}
}