// 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.Dam.Data.Properties;
using Deltares.Dam.Data.Sensors;
using Deltares.Dam.Data.Geometry2DImporter;
using Deltares.DamEngine.Data.Standard;
using Deltares.DamEngine.Io;
using Deltares.DamEngine.Io.XmlInput;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Standard.Logging;
using Sensor = Deltares.Dam.Data.Sensors.Sensor;
using SensorLocation = Deltares.DamEngine.Io.XmlInput.SensorLocation;
using Soil = Deltares.Geotechnics.Soils.Soil;
using SoilProfile1D = Deltares.Geotechnics.Soils.SoilProfile1D;
using SoilProfile2D = Deltares.DamEngine.Io.XmlInput.SoilProfile2D;
using SurfaceLine = Deltares.DamEngine.Io.XmlInput.SurfaceLine;
namespace Deltares.Dam.Data.DamEngineIo;
///
/// Create XML Input object from DAM UI project
///
public class FillXmlInputFromDamUi
{
///
/// Creates the input.
///
/// The dam project data.
///
public static Input CreateInput(DamProjectData damProjectData)
{
// First of all, check that there is a dike
ThrowHelper.ThrowIfArgumentNull(damProjectData.WaterBoard, nameof(damProjectData.WaterBoard), StringResourceNames.NoDikeDefined);
Dike dike = damProjectData.WaterBoard.Dikes[0];
// Process locations
string soilProfileDirectory = Path.Combine(damProjectData.ProjectPath, dike.MapForSoilGeometries2D);
var soilProfiles2DToSerialize = new List();
List filteredJobs = FilterLocationJobsWithSoilProfiles(damProjectData.SelectedLocationJobs,
soilProfileDirectory,
dike.SoilList,
dike.Aquifers,
soilProfiles2DToSerialize).ToList();
List filteredLocations = filteredJobs.Select(loc => loc.Location).ToList();
ValidateDamProjectData(damProjectData, filteredLocations);
var input = new Input
{
ProjectPath = damProjectData.ProjectPath,
CalculationMap = damProjectData.CalculationMap,
MaxCalculationCoresSpecified = true,
MaxCalculationCores = damProjectData.MaxCalculationCores
};
TransferAnalysisSpecification(damProjectData, input);
TransferStabilityParameters(damProjectData, input);
input.Locations = new DamEngine.Io.XmlInput.Location[filteredLocations.Count];
TransferLocations(filteredLocations, input.Locations);
// Process segments
IList usedSegments = DetermineUsedSegments(filteredLocations);
if (usedSegments != null)
{
input.Segments = new DamEngine.Io.XmlInput.Segment[usedSegments.Count];
TransferSegments(usedSegments, input.Segments);
}
// Process surface lines
List usedSurfaceLines = DetermineUsedSurfaceLines(filteredLocations);
input.SurfaceLines = new SurfaceLine[usedSurfaceLines.Count];
TransferSurfaceLines(usedSurfaceLines, input.SurfaceLines);
// Process soil profiles 1D
List usedSoilProfiles1D = null;
if (dike.SoilProfiles != null && dike.SoilProfiles.Count > 0)
{
usedSoilProfiles1D = DetermineUsedSoilProfiles1D(usedSegments);
input.SoilProfiles1D = new DamEngine.Io.XmlInput.SoilProfile1D[usedSoilProfiles1D.Count];
TransferSoilProfiles1D(usedSoilProfiles1D, input.SoilProfiles1D);
}
input.SoilProfiles2D = soilProfiles2DToSerialize.ToArray();
// Process soils
List usedSoils = DetermineUsedSoils(dike.SoilList.Soils, usedSoilProfiles1D, soilProfiles2DToSerialize, filteredLocations);
input.Soils = new DamEngine.Io.XmlInput.Soil[dike.SoilList.Soils.Count];
TransferSoils(usedSoils, input.Soils);
TransferTrafficLoadDegreeOfConsolidation(dike.TrafficLoadDegreeOfConsolidations, usedSoils, input);
if (damProjectData.InputTimeSerieCollection != null)
{
input.OperationalInputTimeSeries = new DamEngine.Io.XmlInput.TimeSerie[damProjectData.InputTimeSerieCollection.Series.Count];
TransferInputTimeSeries(damProjectData.InputTimeSerieCollection, input.OperationalInputTimeSeries);
}
if (damProjectData.SensorData != null)
{
input.SensorData = new InputSensorData();
TransferSensorData(damProjectData.SensorData, input.SensorData);
}
return input;
}
private static IList DetermineUsedSegments(List localLocations)
{
var usedSegments = new List();
foreach (Location location in localLocations)
{
if (!usedSegments.Any(sl => sl.Name.Equals(location.Segment.Name)))
{
usedSegments.Add(location.Segment);
}
}
return usedSegments;
}
private static List DetermineUsedSurfaceLines(IList locations)
{
var usedSurfaceLines = new List();
foreach (Location location in locations)
{
SurfaceLine2 crtSurfaceLine = location.LocalXZSurfaceLine2;
if (!usedSurfaceLines.Any(sl => sl.Name.Equals(crtSurfaceLine.Name)))
{
usedSurfaceLines.Add(crtSurfaceLine);
}
}
return usedSurfaceLines;
}
private static List DetermineUsedSoilProfiles1D(IList segments)
{
var usedSoilProfiles1D = new List();
foreach (Segment segment in segments)
{
foreach (SoilGeometryProbability soilProfileProbability in segment.SoilProfileProbabilities.Where(spp => spp.SoilProfileType == SoilProfileType.SoilProfile1D))
{
if (!usedSoilProfiles1D.Any(usp => usp.Name.Equals(soilProfileProbability.SoilProfile.Name)))
{
usedSoilProfiles1D.Add(soilProfileProbability.SoilProfile);
}
}
}
return usedSoilProfiles1D;
}
private static List DetermineUsedSoils(List allSoils, List soilProfile1Ds, List soilProfile2Ds, List locations)
{
List usedSoils = DetermineUsedSoilsFromSoilProfiles1D(soilProfile1Ds);
DetermineUsedSoilsFromSoilProfiles2D(allSoils, soilProfile2Ds, usedSoils);
DetermineUsedSoilsFromLocations(allSoils, locations, usedSoils);
return usedSoils;
}
private static void DetermineUsedSoilsFromLocations(List allSoils, List locations, List usedSoils)
{
foreach (Location location in locations)
{
// Add the soil materials used as dike embankment material in Locations
if (!usedSoils.Any(usedSoil => string.Equals(usedSoil.Name, location.DikeEmbankmentMaterial, StringComparison.OrdinalIgnoreCase)))
{
usedSoils.Add(allSoils.First(soil => string.Equals(soil.Name, location.DikeEmbankmentMaterial, StringComparison.OrdinalIgnoreCase)));
}
// Add the soil materials used as shoulder embankment material in Locations
if (location.ShoulderEmbankmentMaterial != "" && !usedSoils.Any(usedSoil => string.Equals(usedSoil.Name, location.ShoulderEmbankmentMaterial, StringComparison.OrdinalIgnoreCase)))
{
usedSoils.Add(allSoils.First(soil => string.Equals(soil.Name, location.ShoulderEmbankmentMaterial, StringComparison.OrdinalIgnoreCase)));
}
}
}
private static void DetermineUsedSoilsFromSoilProfiles2D(List allSoils, List soilProfile2Ds, List usedSoils)
{
if (soilProfile2Ds != null && soilProfile2Ds.Count > 0)
{
foreach (SoilProfile2D soilProfile2D in soilProfile2Ds)
{
foreach (SoilProfile2DLayer2D layer2D in soilProfile2D.Layers2D)
{
if (!usedSoils.Any(usedSoil => string.Equals(usedSoil.Name, layer2D.SoilName, StringComparison.OrdinalIgnoreCase)))
{
usedSoils.Add(allSoils.First(soil => string.Equals(soil.Name, layer2D.SoilName, StringComparison.OrdinalIgnoreCase)));
}
}
}
}
}
private static List DetermineUsedSoilsFromSoilProfiles1D(List soilProfile1Ds)
{
var usedSoils = new List();
if (soilProfile1Ds != null)
{
foreach (SoilProfile1D soilProfile1D in soilProfile1Ds)
{
foreach (Soil soil in soilProfile1D.Soils)
{
if (!usedSoils.Any(usp => string.Equals(usp.Name, soil.Name, StringComparison.OrdinalIgnoreCase)))
{
usedSoils.Add(soil);
}
}
}
}
return usedSoils;
}
private static void TransferSensorData(SensorData sensorData, InputSensorData inputSensorData)
{
// Transfer sensor groups
var sensorGroupIndex = 0;
inputSensorData.SensorGroups = new SensorGroup[sensorData.SensorGroups.Count];
foreach (Group sensorGroup in sensorData.SensorGroups)
{
var inputSensorGroup = new SensorGroup();
inputSensorGroup.SensorIds = new SensorGroupSensorIds[sensorGroup.SensorCount];
inputSensorGroup.Id = sensorGroup.ID;
var sensorIdIndex = 0;
foreach (Sensor sensor in sensorGroup.SensorArray)
{
inputSensorGroup.SensorIds[sensorIdIndex] = new SensorGroupSensorIds
{
SensorId = sensor.ID
};
sensorIdIndex++;
}
inputSensorData.SensorGroups[sensorGroupIndex] = inputSensorGroup;
sensorGroupIndex++;
}
// Transfer sensor locations
var senserLocationIndex = 0;
inputSensorData.SensorLocations = new SensorLocation[sensorData.SensorLocations.Count];
foreach (Sensors.SensorLocation sensorLocation in sensorData.SensorLocations)
{
var inputSensorLocation = new SensorLocation();
inputSensorLocation.GroupId = sensorLocation.GroupID;
inputSensorLocation.LocationId = sensorLocation.LocationName;
inputSensorLocation.SourceTypePl1PlLineOffsetBelowDikeToeAtPolder = ConversionHelper.ConvertToInputDataSourceTypeSensors(sensorLocation.SourceTypePl1PlLineOffsetBelowDikeToeAtPolder);
inputSensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtPolder = ConversionHelper.ConvertToInputDataSourceTypeSensors(sensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtPolder);
inputSensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtRiver = ConversionHelper.ConvertToInputDataSourceTypeSensors(sensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtRiver);
inputSensorLocation.SourceTypePl1PlLineOffsetBelowShoulderBaseInside = ConversionHelper.ConvertToInputDataSourceTypeSensors(sensorLocation.SourceTypePl1PlLineOffsetBelowShoulderBaseInside);
inputSensorLocation.SourceTypePl1WaterLevelAtRiver = ConversionHelper.ConvertToInputDataSourceTypeSensors(sensorLocation.SourceTypePl1WaterLevelAtRiver);
inputSensorLocation.SourceTypePl1WaterLevelAtPolder = ConversionHelper.ConvertToInputDataSourceTypeSensors(sensorLocation.SourceTypePl1WaterLevelAtPolder);
inputSensorLocation.SourceTypePl3 = ConversionHelper.ConvertToInputDataSourceTypeSensors(sensorLocation.SourceTypePl3);
inputSensorLocation.SourceTypePl4 = ConversionHelper.ConvertToInputDataSourceTypeSensors(sensorLocation.SourceTypePl4);
inputSensorData.SensorLocations[senserLocationIndex] = inputSensorLocation;
senserLocationIndex++;
}
// Transfer sensors
inputSensorData.Sensors = new DamEngine.Io.XmlInput.Sensor[sensorData.Sensors.Count];
var sensorIndex = 0;
foreach (Sensor sensor in sensorData.Sensors)
{
var inputSensor = new DamEngine.Io.XmlInput.Sensor();
inputSensor.Id = sensor.ID;
inputSensor.Name = sensor.Name;
inputSensor.RelativeLocation = sensor.RelativeLocation;
inputSensor.SensorType = ConversionHelper.ConvertToInputSensorType(sensor.Type);
inputSensor.PlLineMapping = new SensorPlLineMapping[sensor.PLLineMappings.Length];
var mappingIndex = 0;
foreach (PLLineType plLineMapping in sensor.PLLineMappings)
{
inputSensor.PlLineMapping[mappingIndex] = new SensorPlLineMapping
{
PLineType = ConversionHelper.ConvertToInputPlLineType(plLineMapping)
};
mappingIndex++;
}
inputSensorData.Sensors[sensorIndex] = inputSensor;
sensorIndex++;
}
}
private static void TransferInputTimeSeries(TimeSerieCollection inputTimeSerieCollection, DamEngine.Io.XmlInput.TimeSerie[] operationalInputTimeSeries)
{
var timeSerieIndex = 0;
foreach (TimeSerie timeSerie in inputTimeSerieCollection.Series)
{
var inputTimeSerie = new DamEngine.Io.XmlInput.TimeSerie();
inputTimeSerie.Entries = new TimeSerieEntries();
inputTimeSerie.Entries.TimeSerieEntry = new TimeSerieEntriesTimeSerieEntry[timeSerie.Entries.Count];
inputTimeSerie.LocationId = timeSerie.LocationId;
inputTimeSerie.ParameterId = timeSerie.ParameterId;
inputTimeSerie.ForecastDateTime = timeSerie.ForecastDateTime;
inputTimeSerie.StartDateTime = timeSerie.StartDateTime;
inputTimeSerie.EndDateTime = timeSerie.EndDateTime;
inputTimeSerie.MissVal = timeSerie.MissVal;
inputTimeSerie.Units = timeSerie.Units;
var timeSerieEntryIndex = 0;
foreach (TimeSerieEntry timestepEntry in timeSerie.Entries)
{
var timeStep = new TimeSerieEntriesTimeSerieEntry
{
DateTime = timestepEntry.DateTime,
Value = timestepEntry.Value
};
inputTimeSerie.Entries.TimeSerieEntry[timeSerieEntryIndex] = timeStep;
timeSerieEntryIndex++;
}
operationalInputTimeSeries[timeSerieIndex] = inputTimeSerie;
timeSerieIndex++;
}
}
private static void TransferAnalysisSpecification(DamProjectData damProjectData, Input input)
{
input.DamProjectType = ConversionHelper.ConvertToInputDamProjectType(damProjectData.DamProjectType);
if (damProjectData.DamProjectCalculationSpecification.CurrentSpecification != null)
{
input.FailureMechanismSystemType = ConversionHelper.ConvertToInputFailureMechanismSystemType(damProjectData.DamProjectCalculationSpecification.CurrentSpecification.FailureMechanismSystemType);
input.AnalysisTypeSpecified = (input.DamProjectType == InputDamProjectType.Design);
if (input.AnalysisTypeSpecified)
{
input.AnalysisType = ConversionHelper.ConvertToInputAnalysisType(DamProjectCalculationSpecification.SelectedAnalysisType);
}
input.PipingModelTypeSpecified = input.FailureMechanismSystemType == InputFailureMechanismSystemType.Piping;
if (input.PipingModelTypeSpecified)
{
input.PipingModelType = ConversionHelper.ConvertToInputPipingModelType(damProjectData.DamProjectCalculationSpecification.CurrentSpecification.PipingModelType);
}
input.StabilityModelTypeSpecified = input.FailureMechanismSystemType == InputFailureMechanismSystemType.StabilityInside ||
input.FailureMechanismSystemType == InputFailureMechanismSystemType.StabilityOutside;
if (input.StabilityModelTypeSpecified)
{
input.StabilityModelType = ConversionHelper.ConvertToInputStabilityModelType(damProjectData.DamProjectCalculationSpecification.CurrentSpecification.StabilityModelType);
}
}
}
private static void TransferStabilityParameters(DamProjectData damProjectData, Input input)
{
if (damProjectData.DamProjectCalculationSpecification != null && damProjectData.DamProjectCalculationSpecification.CurrentSpecification != null)
{
DamFailureMechanismeCalculationSpecification curSpec = damProjectData.DamProjectCalculationSpecification.CurrentSpecification;
if (curSpec.FailureMechanismeParamatersMStab != null && curSpec.FailureMechanismeParamatersMStab.MStabParameters != null)
{
input.StabilityParameters = new StabilityParameters();
input.StabilityParameters.SearchMethod = ConversionHelper.ConvertToInputSearchMethod(curSpec.FailureMechanismeParamatersMStab.MStabParameters.SearchMethod);
SlipCircleDefinition slipCircleDefinition = curSpec.FailureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition;
if (slipCircleDefinition != null)
{
input.StabilityParameters.UpliftVanGridDetermination = ConversionHelper.ConvertToInputUpliftVanGridDetermination(slipCircleDefinition.UpliftVanGridSizeDetermination);
input.StabilityParameters.BishopSearchAreaDetermination = ConversionHelper.ConvertToInputBishopSearchAreaDetermination(slipCircleDefinition.BishopSearchAreaDetermination);
input.StabilityParameters.BishopTangentLinesDistanceSpecified = true;
input.StabilityParameters.BishopTangentLinesDistance = slipCircleDefinition.BishopTangentLinesDistance;
input.StabilityParameters.BishopGridVerticalPointsCountSpecified = true;
input.StabilityParameters.BishopGridVerticalPointsCount = slipCircleDefinition.BishopGridVerticalPointCount;
input.StabilityParameters.BishopGridVerticalPointsDistanceSpecified = true;
input.StabilityParameters.BishopGridVerticalPointsDistance = slipCircleDefinition.BishopGridVerticalPointDistance;
input.StabilityParameters.BishopGridHorizontalPointsCountSpecified = true;
input.StabilityParameters.BishopGridHorizontalPointsCount = slipCircleDefinition.BishopGridHorizontalPointCount;
input.StabilityParameters.BishopGridHorizontalPointsDistanceSpecified = true;
input.StabilityParameters.BishopGridHorizontalPointsDistance = slipCircleDefinition.BishopGridHorizontalPointDistance;
input.StabilityParameters.UpliftVanTangentLinesDefinitionSpecified = true;
input.StabilityParameters.UpliftVanTangentLinesDefinition = ConversionHelper.ConvertToInputTangentLinesDefinition(slipCircleDefinition.UpliftVanTangentLinesDefinition);
input.StabilityParameters.UpliftVanTangentLinesDistanceSpecified = true;
input.StabilityParameters.UpliftVanTangentLinesDistance = slipCircleDefinition.UpliftVanTangentLinesDistance;
input.StabilityParameters.UpliftVanGridLeftVerticalPointsCountSpecified = true;
input.StabilityParameters.UpliftVanGridLeftVerticalPointsCount = slipCircleDefinition.UpliftVanLeftGridVerticalPointCount;
input.StabilityParameters.UpliftVanGridLeftVerticalPointsDistanceSpecified = true;
input.StabilityParameters.UpliftVanGridLeftVerticalPointsDistance = slipCircleDefinition.UpliftVanLeftGridVerticalPointDistance;
input.StabilityParameters.UpliftVanGridLeftHorizontalPointsCountSpecified = true;
input.StabilityParameters.UpliftVanGridLeftHorizontalPointsCount = slipCircleDefinition.UpliftVanLeftGridHorizontalPointCount;
input.StabilityParameters.UpliftVanGridLeftHorizontalPointsDistanceSpecified = true;
input.StabilityParameters.UpliftVanGridLeftHorizontalPointsDistance = slipCircleDefinition.UpliftVanLeftGridHorizontalPointDistance;
input.StabilityParameters.UpliftVanGridRightVerticalPointsCountSpecified = true;
input.StabilityParameters.UpliftVanGridRightVerticalPointsCount = slipCircleDefinition.UpliftVanRightGridVerticalPointCount;
input.StabilityParameters.UpliftVanGridRightVerticalPointsDistanceSpecified = true;
input.StabilityParameters.UpliftVanGridRightVerticalPointsDistance = slipCircleDefinition.UpliftVanRightGridVerticalPointDistance;
input.StabilityParameters.UpliftVanGridRightHorizontalPointsCountSpecified = true;
input.StabilityParameters.UpliftVanGridRightHorizontalPointsCount = slipCircleDefinition.UpliftVanRightGridHorizontalPointCount;
input.StabilityParameters.UpliftVanGridRightHorizontalPointsDistanceSpecified = true;
input.StabilityParameters.UpliftVanGridRightHorizontalPointsDistance = slipCircleDefinition.UpliftVanRightGridHorizontalPointDistance;
}
}
}
}
private static void ValidateDamProjectData(DamProjectData damProjectData, List selectedLocations)
{
if (damProjectData.WaterBoard.Dikes == null || damProjectData.WaterBoard.Dikes.Count != 1)
{
throw new ArgumentException(Resources.DikeShouldContainExactly1Dike);
}
Dike dike = damProjectData.WaterBoard.Dikes[0];
ThrowHelper.ThrowIfArgumentNull(dike.Locations, nameof(dike.Locations), StringResourceNames.NoLocationsDefined);
// Following situation should never occur in the UI. Tested because of the check on RiverLevelLow in the code below
DamFailureMechanismeCalculationSpecification currentSpecification = damProjectData.DamProjectCalculationSpecification.CurrentSpecification;
ThrowHelper.ThrowIfArgumentNull(currentSpecification, nameof(currentSpecification), StringResourceNames.NoCalculationTypeSpecified);
foreach (Location location in selectedLocations)
{
ThrowHelper.ThrowIfArgumentNull(location.Scenarios, nameof(location.Scenarios), StringResourceNames.NoScenariosDefinedInLocation);
foreach (Scenario scenario in location.Scenarios)
{
string errorMessage = string.Format(Resources.NoRiverLevel, location.Name, scenario.LocationScenarioID);
ThrowHelper.ThrowIfArgumentNull(scenario.RiverLevel, nameof(scenario.RiverLevel), errorMessage);
// In code above is tested that CurrentSpecification exists
if (currentSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityOutside)
{
errorMessage = string.Format(Resources.NoRiverLevelLow, location.Name, scenario.LocationScenarioID);
ThrowHelper.ThrowIfArgumentNull(scenario.RiverLevelLow, nameof(scenario.RiverLevelLow), errorMessage);
}
}
}
ThrowHelper.ThrowIfArgumentNull(dike.SurfaceLines2, nameof(dike.SurfaceLines2), StringResourceNames.NoSurfaceLines);
foreach (SurfaceLine2 surfaceLine in dike.SurfaceLines2)
{
if ((surfaceLine.CharacteristicPoints == null) || (surfaceLine.CharacteristicPoints.Count < 1))
{
throw new ArgumentException(string.Format(Resources.SurfaceLineHasNoCharacteristicPoints, surfaceLine.Name));
}
if ((surfaceLine.Geometry == null) || (surfaceLine.Geometry.Count < 2))
{
throw new ArgumentException(string.Format(Resources.SurfaceLineHasNoPoints, surfaceLine.Name));
}
}
ThrowHelper.ThrowIfArgumentNull(dike.SoilList, nameof(dike.SoilList), StringResourceNames.NoSoilsDefinedInProject);
ThrowHelper.ThrowIfArgumentNull(dike.SoilList.Soils, nameof(dike.SoilList.Soils), StringResourceNames.NoSoilsDefinedInProject);
ThrowHelper.ThrowIfArgumentNull(dike.SoilProfiles, nameof(dike.SoilProfiles), StringResourceNames.NoSoilprofiles1DDefinedInProject);
// Check for invalid Id names
foreach (Location location in selectedLocations)
{
if (!IdValidator.IsCorrectName(location.Name))
{
throw new IdValidatorException(string.Format(Resources.LocationInvalidName, location.Name));
}
}
foreach (Segment segment in damProjectData.WaterBoard.Segments)
{
if (!IdValidator.IsCorrectName(segment.Name))
{
throw new IdValidatorException(string.Format(Resources.SegmentInvalidName, segment.Name));
}
}
foreach (SurfaceLine2 surfaceLine2 in dike.SurfaceLines2)
{
if (!IdValidator.IsCorrectName(surfaceLine2.Name))
{
throw new IdValidatorException(string.Format(Resources.SurfaceLineInvalidName, surfaceLine2.Name));
}
}
foreach (SoilProfile1D soilProfile in dike.SoilProfiles)
{
if (!IdValidator.IsCorrectName(soilProfile.Name))
{
throw new IdValidatorException(string.Format(Resources.SoilProfileInvalidName, soilProfile.Name));
}
}
foreach (Soil soil in dike.SoilList.Soils)
{
if (!IdValidator.IsCorrectName(soil.Name))
{
throw new IdValidatorException(string.Format(Resources.SoilInvalidName, soil.Name));
}
}
}
private static void TransferSoils(List soils, DamEngine.Io.XmlInput.Soil[] inputSoils)
{
for (var i = 0; i < soils.Count; i++)
{
Soil soil = soils[i];
var inputSoil = new DamEngine.Io.XmlInput.Soil();
inputSoil.Name = soil.Name;
inputSoil.AbovePhreaticLevelSpecified = !Double.IsNaN(soil.AbovePhreaticLevel);
inputSoil.AbovePhreaticLevel = soil.AbovePhreaticLevel;
inputSoil.BelowPhreaticLevelSpecified = !Double.IsNaN(soil.BelowPhreaticLevel);
inputSoil.BelowPhreaticLevel = soil.BelowPhreaticLevel;
inputSoil.DiameterD70Specified = !Double.IsNaN(soil.DiameterD70);
inputSoil.DiameterD70 = soil.DiameterD70;
inputSoil.PermeabKxSpecified = !Double.IsNaN(soil.PermeabKx);
inputSoil.PermeabKx = soil.PermeabKx;
inputSoil.ShearStrengthModelSpecified = true;
inputSoil.ShearStrengthModel = ConversionHelper.ConvertToSoilShearStrengthModel(soil.ShearStrengthModel);
if (soil.ShearStrengthModel == ShearStrengthModel.StressTable)
{
inputSoil.SigmaTauCurve = new SigmaTauCurveSigmaTauPoint[soil.StressTable.SigmaTaus.Count];
for (var j = 0; j < soil.StressTable.SigmaTaus.Count; j++)
{
inputSoil.SigmaTauCurve[j] = new SigmaTauCurveSigmaTauPoint
{
Sigma = soil.StressTable.SigmaTaus[j].Sigma,
Tau = soil.StressTable.SigmaTaus[j].Tau
};
}
}
if (soil.ShearStrengthModel == ShearStrengthModel.SuTable)
{
inputSoil.SuTable = new SuTableSigmaSuPoint[soil.SuTable.SigmaSus.Count];
for (var j = 0; j < soil.SuTable.SigmaSus.Count; j++)
{
inputSoil.SuTable[j] = new SuTableSigmaSuPoint
{
Sigma = soil.SuTable.SigmaSus[j].Sigma,
Su = soil.SuTable.SigmaSus[j].Su
};
}
}
inputSoil.CohesionSpecified = !Double.IsNaN(soil.Cohesion);
inputSoil.Cohesion = soil.Cohesion;
inputSoil.FrictionAngleSpecified = !Double.IsNaN(soil.FrictionAngle);
inputSoil.FrictionAngle = soil.FrictionAngle;
inputSoil.OcrSpecified = !Double.IsNaN(soil.OCR);
inputSoil.Ocr = soil.OCR;
inputSoil.StrengthIncreaseExponentSpecified = !Double.IsNaN(soil.StrengthIncreaseExponent);
inputSoil.StrengthIncreaseExponent = soil.StrengthIncreaseExponent;
inputSoil.RatioCuPcSpecified = !Double.IsNaN(soil.RatioCuPc);
inputSoil.RatioCuPc = soil.RatioCuPc;
inputSoil.PopSpecified = !Double.IsNaN(soil.POP);
inputSoil.Pop = soil.POP;
inputSoils[i] = inputSoil;
}
}
private static void TransferSurfaceLines(IList dikeSurfaceLines, SurfaceLine[] inputSurfaceLines)
{
for (var i = 0; i < dikeSurfaceLines.Count; i++)
{
SurfaceLine2 surfaceLine = dikeSurfaceLines[i];
var inputSurfaceLine = new SurfaceLine();
inputSurfaceLine.Name = surfaceLine.Name;
inputSurfaceLine.Points = new SurfaceLinePoint[surfaceLine.CharacteristicPoints.Count];
for (var j = 0; j < surfaceLine.CharacteristicPoints.Count; j++)
{
CharacteristicPoint characteristicPoint = surfaceLine.CharacteristicPoints[j];
var inputPoint = new SurfaceLinePoint
{
PointType = ConversionHelper.ConvertToInputPointType(characteristicPoint.CharacteristicPointType),
X = characteristicPoint.X,
Z = characteristicPoint.Z
};
inputSurfaceLine.Points[j] = inputPoint;
}
inputSurfaceLines[i] = inputSurfaceLine;
}
}
private static void TransferLocations(IList dikeLocations, DamEngine.Io.XmlInput.Location[] inputLocations)
{
for (var i = 0; i < dikeLocations.Count; i++)
{
Location location = dikeLocations[i];
var inputLocation = new DamEngine.Io.XmlInput.Location();
inputLocation.Name = location.Name;
inputLocation.DistanceToEntryPoint = location.DistanceToEntryPoint;
inputLocation.DistanceToEntryPointSpecified = true;
inputLocation.SurfaceLineName = location.LocalXZSurfaceLine2.Name;
inputLocation.SegmentName = location.Segment.Name;
var waternetOptions = new LocationWaternetOptions();
waternetOptions.PhreaticLineCreationMethod = ConversionHelper.ConvertToInputPhreaticLineCreationMethod(location.PLLineCreationMethod);
waternetOptions.IntrusionVerticalWaterPressure = ConversionHelper.ConvertToInputIntrusionVerticalWaterPressure(location.IntrusionVerticalWaterPressure ?? IntrusionVerticalWaterPressureType.Standard);
waternetOptions.DampingFactorPl3 = location.DampingFactorPL3;
waternetOptions.DampingFactorPl4 = location.DampingFactorPL4;
waternetOptions.PenetrationLength = location.PenetrationLength;
waternetOptions.SlopeDampingFactor = location.SlopeDampingPiezometricHeightPolderSide;
inputLocation.WaternetOptions = waternetOptions;
inputLocation.DesignScenarios = new LocationDesignScenario[location.Scenarios.Count];
for (var j = 0; j < location.Scenarios.Count; j++)
{
Scenario designScenario = location.Scenarios[j];
var inputDesignScenario = new LocationDesignScenario();
inputDesignScenario.RiverLevel = designScenario.RiverLevel.Value;
inputDesignScenario.Id = designScenario.LocationScenarioID;
inputDesignScenario.RiverLevelLowSpecified = designScenario.RiverLevelLow.HasValue;
inputDesignScenario.RiverLevelLow = designScenario.RiverLevelLow ?? 0.0;
inputDesignScenario.DikeTableHeightSpecified = designScenario.DikeTableHeight.HasValue;
inputDesignScenario.DikeTableHeight = designScenario.DikeTableHeight ?? 0.0;
inputDesignScenario.PlLineOffsetBelowDikeTopAtRiver = designScenario.PlLineOffsetBelowDikeTopAtRiver;
inputDesignScenario.PlLineOffsetBelowDikeTopAtPolder = designScenario.PlLineOffsetBelowDikeTopAtPolder;
inputDesignScenario.PlLineOffsetBelowShoulderBaseInside = designScenario.PlLineOffsetBelowShoulderBaseInside;
inputDesignScenario.PlLineOffsetBelowDikeToeAtPolder = designScenario.PlLineOffsetBelowDikeToeAtPolder;
inputDesignScenario.PlLineOffsetBelowDikeCrestMiddleSpecified = designScenario.UsePlLineOffsetBelowDikeCrestMiddle ?? false;
inputDesignScenario.PlLineOffsetBelowDikeCrestMiddle = designScenario.PlLineOffsetBelowDikeCrestMiddle ?? 0.0;
inputDesignScenario.PlLineOffsetFactorBelowShoulderCrestSpecified = designScenario.UsePlLineOffsetFactorBelowShoulderCrest ?? false;
inputDesignScenario.PlLineOffsetFactorBelowShoulderCrest = designScenario.PlLineOffsetFactorBelowShoulderCrest ?? 0.0;
inputDesignScenario.HeadPl3Specified = designScenario.HeadPl3.HasValue;
inputDesignScenario.HeadPl3 = designScenario.HeadPl3 ?? 0.0;
inputDesignScenario.HeadPl4Specified = designScenario.HeadPl4.HasValue;
inputDesignScenario.HeadPl4 = designScenario.HeadPl4 ?? 0.0;
inputDesignScenario.UpliftCriterionStability = designScenario.UpliftCriterionStability;
inputDesignScenario.UpliftCriterionPiping = designScenario.UpliftCriterionPiping;
inputDesignScenario.RequiredSafetyFactorStabilityInnerSlope = designScenario.RequiredSafetyFactorStabilityInnerSlope;
inputDesignScenario.RequiredSafetyFactorStabilityOuterSlope = designScenario.RequiredSafetyFactorStabilityOuterSlope;
inputDesignScenario.RequiredSafetyFactorPiping = designScenario.RequiredSafetyFactorPiping;
inputDesignScenario.PolderLevel = designScenario.PolderLevel;
inputDesignScenario.HeadPl2Specified = designScenario.HeadPl2.HasValue;
inputDesignScenario.HeadPl2 = designScenario.HeadPl2 ?? 0.0;
inputLocation.DesignScenarios[j] = inputDesignScenario;
}
inputLocation.DikeEmbankmentMaterial = location.DikeEmbankmentMaterial;
inputLocation.StabilityOptions = new LocationStabilityOptions
{
ZoneType = ConversionHelper.ConvertToInputZoneType(location.StabilityZoneType),
ForbiddenZoneFactorSpecified = true,
ForbiddenZoneFactor = location.ForbiddenZoneFactor,
TrafficLoadSpecified = true,
TrafficLoad = location.TrafficLoad,
TrafficLoadDegreeOfConsolidationSpecified = location.TL_DegreeOfConsolidation.HasValue,
TrafficLoadDegreeOfConsolidation = location.TL_DegreeOfConsolidation ?? 0.0,
MinimumCircleDepthSpecified = true,
MinimumCircleDepth = location.MinimalCircleDepth
};
// Design options
var designOptions = new LocationDesignOptions();
designOptions.RedesignDikeHeight = location.RedesignDikeHeight;
designOptions.RedesignDikeShoulder = location.RedesignDikeShoulder;
designOptions.ShoulderEmbankmentMaterial = location.ShoulderEmbankmentMaterial;
designOptions.StabilityShoulderGrowSlope = location.StabilityShoulderGrowSlope;
designOptions.StabilityShoulderGrowDeltaX = location.StabilityShoulderGrowDeltaX;
designOptions.StabilitySlopeAdaptionDeltaX = location.StabilitySlopeAdaptionDeltaX;
designOptions.SlopeAdaptionStartCotangent = location.SlopeAdaptionStartCotangent;
designOptions.SlopeAdaptionEndCotangent = location.SlopeAdaptionEndCotangent;
designOptions.SlopeAdaptionStepCotangent = location.SlopeAdaptionStepCotangent;
designOptions.NewDikeTopWidthSpecified = location.UseNewDikeTopWidth;
designOptions.NewDikeTopWidth = location.NewDikeTopWidth;
designOptions.NewDikeSlopeInsideSpecified = location.UseNewDikeSlopeInside;
designOptions.NewDikeSlopeInside = location.NewDikeSlopeInside;
designOptions.NewDikeSlopeOutsideSpecified = location.UseNewDikeSlopeOutside;
designOptions.NewDikeSlopeOutside = location.NewDikeSlopeOutside;
designOptions.NewShoulderTopSlopeSpecified = location.UseNewShoulderTopSlope;
designOptions.NewShoulderTopSlope = location.NewShoulderTopSlope;
designOptions.NewShoulderBaseSlopeSpecified = location.UseNewShoulderBaseSlope;
designOptions.NewShoulderBaseSlope = location.NewShoulderBaseSlope;
designOptions.NewMaxHeightShoulderAsFractionSpecified = location.UseNewMaxHeightShoulderAsFraction;
designOptions.NewMaxHeightShoulderAsFraction = location.NewMaxHeightShoulderAsFraction;
designOptions.NewMinDistanceDikeToeStartDitchSpecified = location.UseNewMinDistanceDikeToeStartDitch;
designOptions.NewMinDistanceDikeToeStartDitch = location.NewMinDistanceDikeToeStartDitch;
designOptions.UseNewDitchDefinition = location.UseNewDitchDefinition;
designOptions.NewWidthDitchBottomSpecified = location.UseNewDitchDefinition;
designOptions.NewWidthDitchBottom = location.NewWidthDitchBottom;
designOptions.NewSlopeAngleDitchSpecified = location.UseNewDitchDefinition;
designOptions.NewSlopeAngleDitch = location.NewSlopeAngleDitch;
designOptions.NewDepthDitchSpecified = location.UseNewDitchDefinition;
designOptions.NewDepthDitch = location.NewDepthDitch;
designOptions.StabilityDesignMethod = ConversionHelper.ConvertToInputStabilityDesignMethod(location.StabilityDesignMethod);
inputLocation.DesignOptions = designOptions;
inputLocations[i] = inputLocation;
}
}
private static void TransferSoilProfiles1D(IList dikeSoilProfiles, DamEngine.Io.XmlInput.SoilProfile1D[] inputSoilProfiles1D)
{
int profilesCount = dikeSoilProfiles.Count;
for (var i = 0; i < profilesCount; i++)
{
SoilProfile1D soilProfile1D = dikeSoilProfiles[i];
var inputSoilProfile1D = new DamEngine.Io.XmlInput.SoilProfile1D
{
Name = soilProfile1D.Name,
BottomLevel = soilProfile1D.BottomLevel,
Layers1D = new SoilProfile1DLayer1D[soilProfile1D.LayerCount]
};
AddLayers1D(soilProfile1D, inputSoilProfile1D);
inputSoilProfiles1D[i] = inputSoilProfile1D;
}
}
private static void AddLayers1D(SoilProfile1D soilProfile1D, DamEngine.Io.XmlInput.SoilProfile1D inputSoilProfile1D)
{
for (var i = 0; i < soilProfile1D.LayerCount; i++)
{
SoilLayer1D layer = soilProfile1D.Layers[i];
var inputLayer = new SoilProfile1DLayer1D
{
Name = "L" + i,
SoilName = layer.Soil.Name,
TopLevel = layer.TopLevel,
IsAquifer = layer.IsAquifer,
WaterpressureInterpolationModel = ConversionHelper.ConvertToInputWaterpressureInterpolationModel(
layer.WaterpressureInterpolationModel)
};
inputSoilProfile1D.Layers1D[i] = inputLayer;
}
}
private static void TransferSegments(IList segments, DamEngine.Io.XmlInput.Segment[] inputSegments)
{
for (var i = 0; i < segments.Count; i++)
{
Segment segment = segments[i];
var inputSegment = new DamEngine.Io.XmlInput.Segment
{
Name = segment.Name
};
AddSoilProfileProbabilities(segment, inputSegment);
inputSegments[i] = inputSegment;
}
}
private static void TransferTrafficLoadDegreeOfConsolidation(IList trafficLoadDegreeOfConsolidations, List usedSoils, Input input)
{
InputTrafficLoadDegreeOfConsolidation[] inputTrafficLoadDegreeOfConsolidations;
if (trafficLoadDegreeOfConsolidations != null && trafficLoadDegreeOfConsolidations.Count > 0)
{
inputTrafficLoadDegreeOfConsolidations = new InputTrafficLoadDegreeOfConsolidation[usedSoils.Count];
var index = 0;
foreach (TrafficLoadDegreeOfConsolidation trafficLoadDegreeOfConsolidation in trafficLoadDegreeOfConsolidations)
{
if (usedSoils.Any(soil => string.Equals(soil.Name, trafficLoadDegreeOfConsolidation.SoilName, StringComparison.OrdinalIgnoreCase)))
{
inputTrafficLoadDegreeOfConsolidations[index] = new InputTrafficLoadDegreeOfConsolidation()
{
SoilName = trafficLoadDegreeOfConsolidation.SoilName,
DegreeOfConsolidation = trafficLoadDegreeOfConsolidation.DegreeOfConsolidation
};
index += 1;
}
}
}
else
{
inputTrafficLoadDegreeOfConsolidations = null;
}
input.TrafficLoadDegreeOfConsolidations = inputTrafficLoadDegreeOfConsolidations;
}
private static void AddSoilProfileProbabilities(Segment segment, DamEngine.Io.XmlInput.Segment inputSegment)
{
if (segment.SoilProfileProbabilities != null)
{
int probabilityCount = segment.SoilProfileProbabilities.Count;
inputSegment.SoilGeometryProbability = new SegmentSoilGeometryProbability[probabilityCount];
for (var i = 0; i < probabilityCount; i++)
{
SoilGeometryProbability soilGeometryProbability = segment.SoilProfileProbabilities[i];
var inputSoilGeometryProbability = new SegmentSoilGeometryProbability();
inputSoilGeometryProbability.Probability = soilGeometryProbability.Probability;
if (soilGeometryProbability.SegmentFailureMechanismType.HasValue)
{
inputSoilGeometryProbability.SegmentFailureMechanismType = ConversionHelper.ConvertToInputSegmentFailureMechanismType(soilGeometryProbability.SegmentFailureMechanismType.Value);
inputSoilGeometryProbability.SegmentFailureMechanismTypeSpecified = true;
}
else
{
inputSoilGeometryProbability.SegmentFailureMechanismTypeSpecified = false;
}
switch (soilGeometryProbability.SoilProfileType)
{
case SoilProfileType.SoilProfile1D:
case SoilProfileType.SoilProfile2D:
inputSoilGeometryProbability.SoilProfileName = soilGeometryProbability.SoilGeometryName;
break;
default:
inputSoilGeometryProbability.SoilProfileName = soilGeometryProbability.SoilGeometry2DName;
break;
}
inputSoilGeometryProbability.SoilProfileType = ConversionHelper.ConvertToInputSoilProfileType(soilGeometryProbability.SoilProfileType);
inputSegment.SoilGeometryProbability[i] = inputSoilGeometryProbability;
}
}
}
///
/// Filters the collection of on whether they have soil profiles to perform calculations with.
///
/// The collection of to filter.
/// The directory to retrieve the soil profiles from.
/// The containing the available soils.
/// The collection of that is imported from csv.>
/// The collection of that is contained
/// by the .
/// A collection of on which calculations can be performed.
private static IEnumerable FilterLocationJobsWithSoilProfiles(IEnumerable locationJobs,
string soilProfileDirectory,
SoilList availableSoils,
IEnumerable aquifers,
ICollection containedSoilProfiles)
{
var validJobs = new List();
var uniqueSoilProfileNames = new HashSet();
foreach (LocationJob locationJob in locationJobs)
{
Location location = locationJob.Location;
try
{
foreach (SoilProfile2D soilProfile in GetSoilProfiles(soilProfileDirectory, location.Segment, availableSoils, aquifers, location.XSoilGeometry2DOrigin))
{
string soilProfileName = soilProfile.Name;
if (!uniqueSoilProfileNames.Contains(soilProfileName))
{
uniqueSoilProfileNames.Add(soilProfileName);
containedSoilProfiles.Add(soilProfile);
}
}
validJobs.Add(locationJob);
}
catch (Exception e) when (e is ConversionException || e is SoilProfileImporterException)
{
LogInvalidLocationJobErrorMessages(location, e.Message);
}
}
return validJobs;
}
private static void LogInvalidLocationJobErrorMessages(Location location, string errorMessage)
{
if (location.Scenarios.Any())
{
foreach (Scenario scenario in location.Scenarios)
{
var message = $"Location '{location.Name}', design scenario '{scenario.LocationScenarioID}': The calculation failed with error message: '{errorMessage}'";
LogManager.Messages.Add(new LogMessage(LogMessageType.Error, null, message));
}
}
else
{
var message = $"Location '{location.Name}': The calculation failed with error message: '{errorMessage}'";
LogManager.Messages.Add(new LogMessage(LogMessageType.Error, null, message));
}
}
///
/// Gets the soil profiles based on the input arguments.
///
/// The directory to retrieve the soil profiles from.
/// The to retrieve the soil profiles for.
/// The containing the available soils.
/// The collection of that is imported from csv.>
///
/// An array of .
/// Thrown when the soil profiles could not be successfully imported.
/// Thrown when the soil profiles could not be successfully converted.
private static IEnumerable GetSoilProfiles(string soilProfileDirectory, Segment segment, SoilList soils,
IEnumerable aquifers, double xSoilGeometry2DOrigin)
{
IEnumerable importedSoilProfiles = SoilProfile2DImporter.Import(soilProfileDirectory, segment, soils, aquifers, xSoilGeometry2DOrigin);
if (importedSoilProfiles == null)
{
return Enumerable.Empty();
}
return importedSoilProfiles.Select(XmlSoilProfile2DConverter.Convert).ToArray();
}
}