// 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.Linq;
using Deltares.Dam.Data;
using Deltares.Dam.Data.DamEngineIo;
using Deltares.Dam.Data.Sensors;
using Deltares.DamEngine.Data.Standard;
using Deltares.DamEngine.Io;
using Deltares.DamEngine.Io.XmlInput;
using Deltares.Geometry;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.Logging;
using KellermanSoftware.CompareNetObjects;
using NUnit.Framework;
using NUnit.Framework.Constraints;
using Location = Deltares.Dam.Data.Location;
using Segment = Deltares.Dam.Data.Segment;
using Sensor = Deltares.Dam.Data.Sensors.Sensor;
using SensorLocation = Deltares.Dam.Data.Sensors.SensorLocation;
using Soil = Deltares.Geotechnics.Soils.Soil;
using SoilProfile1D = Deltares.Geotechnics.Soils.SoilProfile1D;
using SoilProfile2D = Deltares.DamEngine.Io.XmlInput.SoilProfile2D;
using TimeSerie = Deltares.Dam.Data.TimeSerie;
namespace Deltares.Dam.Tests.DamEngineIo
{
[TestFixture]
public class FillXmlInputFromDamUiTests
{
private const AnalysisType expectedAnalysisType = AnalysisType.AdaptGeometry;
private const AnalysisType notExpectedAnalysisType = AnalysisType.NoAdaption;
private const string shoulderEmbankmentMaterial = "ShoulderMat";
private const string dikeEmbankmentMaterial = "DikeMat";
private const int locationCount = 3;
[Test]
public void CanWriteAndReadDamProjectDataToXmlFile()
{
const string inputFilename = "InputFile.xml";
DamProject.ProjectMap = "test project map";
DamProjectData expectedDamProjectData = CreateExampleDamProjectData();
// Write input file
Input expectedInput = FillXmlInputFromDamUi.CreateInput(expectedDamProjectData);
DamXmlSerialization.SaveInputAsXmlFile(inputFilename, expectedInput);
// Init static that is to be loaded with not expected value
DamProjectCalculationSpecification.SelectedAnalysisType = notExpectedAnalysisType;
// Load input file
Input actualInput = DamXmlSerialization.LoadInputFromXmlFile(inputFilename);
DamProjectData actualDamProjectData = FillDamUiFromXmlInput.CreateDamProjectData(actualInput);
CompareSoilLists(actualDamProjectData.WaterBoard.Dikes[0].SoilList, expectedDamProjectData.WaterBoard.Dikes[0].SoilList);
CompareDamProjectData(actualDamProjectData, expectedDamProjectData);
// The soil profiles 2D are not present in the expectedDamProjectData because they are created when calling
// FillXmlInputFromDamUi.CreateInput. That's why they must be checked separately from the Input object.
CompareSoilProfiles2D(actualInput.SoilProfiles2D, expectedInput.SoilProfiles2D);
}
[Test]
public void CanWriteAndReadDamProjectDataToXmlString()
{
DataEventPublisher.IsDataEventPublishStopped = true;
DamProjectData expectedDamProjectData = CreateExampleDamProjectData();
// Write input string
Input input = FillXmlInputFromDamUi.CreateInput(expectedDamProjectData);
string inputXml = DamXmlSerialization.SaveInputAsXmlString(input);
// Init static that is to be loaded with not expected value
DamProjectCalculationSpecification.SelectedAnalysisType = notExpectedAnalysisType;
// Load input string
input = DamXmlSerialization.LoadInputFromXmlString(inputXml);
DamProjectData actualDamProjectData = FillDamUiFromXmlInput.CreateDamProjectData(input);
CompareDamProjectData(actualDamProjectData, expectedDamProjectData);
}
[Test]
public void GivenDamProjectWithValidLocationsWithMixedProfiles_WhenCreatingInput_ThenExpectedProfilesSerialized()
{
// Given
LogManager.Messages.Clear();
const string selectedLocationOneName = "SelectedLocationOne";
const string selectedSegmentOneName = "SelectedSegmentOne";
const string selectedLocationTwoName = "SelectedLocationTwo";
const string selectedSegmentTwoName = "SelectedSegmentTwo";
var selectedLocations = new HashSet(new[]
{
selectedLocationOneName,
selectedLocationTwoName
});
const string firstSoilProfile1DName = "Profile1D - 1";
const string secondSoilProfile1DName = "Profile1D - 2";
const string profile2DName = "Profile2D 1";
var dike = new Dike
{
MapForSoilGeometries2D = @"TestData\FillXMLInputFromDamUI",
SoilList = CreateSoilList(new[]
{
"Soil 1",
"Soil 2",
"Soil 3"
})
};
// Add the soil profile 1D
var firstSoilProfile1D = new SoilProfile1D
{
Name = firstSoilProfile1DName
};
var secondSoilProfile1D = new SoilProfile1D
{
Name = secondSoilProfile1DName
};
dike.SoilProfiles.AddRange(new[]
{
firstSoilProfile1D,
secondSoilProfile1D
});
// Add the locations with the segments
dike.Locations.AddRange(new[]
{
CreateSimpleLocationWithSoilProfile1DSegment(selectedLocationOneName, selectedSegmentOneName, firstSoilProfile1D),
CreateSimpleLocationWithSoilProfile1DSegment("DoesNotMatterLocation", "DoesNotMatterSegment", secondSoilProfile1D),
CreateSimpleLocationWithSoilProfile2DSegment(selectedLocationTwoName, selectedSegmentTwoName, profile2DName)
});
// Create the project to serialize
var waterBoard = new WaterBoard
{
Dikes = new List
{
dike
}
};
var projectData = new DamProjectData();
FillAnalysisSpecification(projectData);
FillStabilityParameters(projectData);
DamProject.ProjectMap = ""; // Set the folder to be empty so that it runs in the current test directory
projectData.WaterBoard = waterBoard;
foreach (LocationJob locationJob in projectData.LocationJobs)
{
if (selectedLocations.Contains(locationJob.Name))
{
locationJob.Run = true;
}
}
// Precondition
// Assert that the "NotCalculated" calculations are not selected to verify that these:
// - Locations and segments do not end up in the input
// - Do not generate an error message in case something goes wrong.
Assert.That(projectData.SelectedLocationJobs.Select(job => job.Name), Is.EquivalentTo(selectedLocations));
// When
Input input = FillXmlInputFromDamUi.CreateInput(projectData);
Assert.Multiple(() =>
{
// Then
// Note that the original test setup of DAMProject --> XML --> DAMProject does not
// work in this context, as there is NO field within DAMProject to contain the SoilProfile2D
// The only way to assert that the selected locations, segments and their profiles are present,
// is to verify the XMLInput objects that are generated by the CreateInput() call.
Assert.That(input.Locations.Select(loc => loc.Name), Is.EquivalentTo(selectedLocations));
Assert.That(input.Segments.Select(segment => segment.Name), Is.EquivalentTo(new[]
{
selectedSegmentOneName,
selectedSegmentTwoName
}));
});
DamEngine.Io.XmlInput.Segment segmentWith1DProfile = input.Segments.Single(s => string.Equals(s.Name, selectedSegmentOneName));
Assert.That(segmentWith1DProfile.SoilGeometryProbability.All(prob => prob.SoilProfileType == ConversionHelper.ConvertToInputSoilProfileType(SoilProfileType.SoilProfile1D)), Is.True);
DamEngine.Io.XmlInput.Segment segmentWith2DProfile = input.Segments.Single(s => string.Equals(s.Name, selectedSegmentTwoName));
Assert.Multiple(() =>
{
Assert.That(segmentWith2DProfile.SoilGeometryProbability.All(prob => prob.SoilProfileType == ConversionHelper.ConvertToInputSoilProfileType(SoilProfileType.SoilProfile2D)), Is.True);
Assert.That(input.SoilProfiles1D.Select(profile => profile.Name), Is.EquivalentTo(new[]
{
firstSoilProfile1DName
}));
Assert.That(input.SoilProfiles2D.Select(profile => profile.Name), Is.EquivalentTo(new[]
{
profile2DName + ".stix"
}));
});
}
[Test]
public void GivenDamProjectWithValidLocationsWith2DProfiles_WhenCreatingInput_ThenSelectedLocationsSerialized()
{
// Given
LogManager.Messages.Clear();
const string selectedLocationOneName = "SelectedLocationOne";
const string selectedSegmentOneName = "SelectedSegmentOne";
const string segmentOneSoilProfileName = "Profile2D 1.stix";
const string selectedLocationTwoName = "SelectedLocationTwo";
const string selectedSegmentTwoName = "SelectedSegmentTwo";
const string segmentTwoSoilProfileName = "Profile2D 2.stix";
var selectedLocations = new HashSet(new[]
{
selectedLocationOneName,
selectedLocationTwoName
});
// Add the locations with the segments
var dike = new Dike
{
MapForSoilGeometries2D = @"TestData\FillXMLInputFromDamUI",
SoilList = CreateSoilList(new[]
{
"Soil 1",
"Soil 2",
"Soil 3"
})
};
dike.Locations.AddRange(new[]
{
CreateSimpleLocationWithSoilProfile2DSegment(selectedLocationOneName, selectedSegmentOneName, segmentOneSoilProfileName),
CreateSimpleLocationWithSoilProfile2DSegment("LocationTwo", "Segment", "DoesNotExist.stix"),
CreateSimpleLocationWithSoilProfile2DSegment(selectedLocationTwoName, selectedSegmentTwoName, segmentTwoSoilProfileName)
});
// Create the project to serialize
var waterBoard = new WaterBoard
{
Dikes = new List
{
dike
}
};
var projectData = new DamProjectData();
FillAnalysisSpecification(projectData);
FillStabilityParameters(projectData);
DamProject.ProjectMap = ""; // Set the folder to be empty so that it runs in the current test directory
projectData.WaterBoard = waterBoard;
foreach (LocationJob locationJob in projectData.LocationJobs)
{
if (selectedLocations.Contains(locationJob.Name))
{
locationJob.Run = true;
}
}
// Preconditions
// Assert that the "NotCalculated" calculations are not selected to verify that these:
// - Locations and segments do not end up in the input
// - Do not generate an error message in case something goes wrong.
Assert.That(projectData.SelectedLocationJobs.Select(job => job.Name), Is.EquivalentTo(selectedLocations));
// When
Input input = FillXmlInputFromDamUi.CreateInput(projectData);
// Then
// Note that the original test setup of DAMProject --> XML --> DAMProject does not
// work in this context, as there is NO field within DAMProject to contain the SoilProfile2D
// The only way to assert that the selected locations, segments and their profiles are present,
// is to verify the XMLInput objects that are generated by the CreateInput() call.
Assert.That(input.Locations.Select(loc => loc.Name), Is.EquivalentTo(selectedLocations));
Assert.That(input.Segments.Select(segment => segment.Name), Is.EquivalentTo(new[]
{
selectedSegmentOneName,
selectedSegmentTwoName
}));
IEnumerable segmentWith2DProfile = input.Segments.Where(s => string.Equals(s.Name, selectedSegmentOneName) || string.Equals(s.Name, selectedSegmentTwoName));
IEnumerable probabilities = segmentWith2DProfile.SelectMany(p => p.SoilGeometryProbability);
Assert.That(probabilities.All(prob => prob.SoilProfileType == ConversionHelper.ConvertToInputSoilProfileType(SoilProfileType.SoilProfile2D)), Is.True);
Assert.That(input.SoilProfiles2D.Select(profile => profile.Name), Is.EquivalentTo(new[]
{
segmentOneSoilProfileName,
segmentTwoSoilProfileName
}));
}
[Test]
public void GivenDamProjectWithValidLocationsWithTheSame2DProfiles_WhenCreatingInput_ThenSelectedLocationsAndOneSoilProfileSerialized()
{
// Given
LogManager.Messages.Clear();
const string selectedLocationOneName = "SelectedLocationOne";
const string selectedSegmentOneName = "SelectedSegmentOne";
const string soilProfileName = "Profile2D 1.stix";
const string selectedLocationTwoName = "SelectedLocationTwo";
const string selectedSegmentTwoName = "SelectedSegmentTwo";
// Add the locations with the segments
var dike = new Dike
{
MapForSoilGeometries2D = @"TestData\FillXMLInputFromDamUI",
SoilList = CreateSoilList(new[]
{
"Soil 1",
"Soil 2"
})
};
dike.Locations.AddRange(new[]
{
CreateSimpleLocationWithSoilProfile2DSegment(selectedLocationOneName, selectedSegmentOneName, soilProfileName),
CreateSimpleLocationWithSoilProfile2DSegment(selectedLocationTwoName, selectedSegmentTwoName, soilProfileName)
});
// Create the project to serialize
var waterBoard = new WaterBoard
{
Dikes = new List
{
dike
}
};
var projectData = new DamProjectData();
FillAnalysisSpecification(projectData);
FillStabilityParameters(projectData);
DamProject.ProjectMap = ""; // Set the folder to be empty so that it runs in the current test directory
projectData.WaterBoard = waterBoard;
foreach (LocationJob locationJob in projectData.LocationJobs)
{
locationJob.Run = true;
}
// When
Input input = FillXmlInputFromDamUi.CreateInput(projectData);
// Then
// Note that the original test setup of DAMProject --> XML --> DAMProject does not
// work in this context, as there is NO field within DAMProject to contain the SoilProfile2D
// The only way to assert that the selected locations, segments and their profiles are present,
// is to verify the XMLInput objects that are generated by the CreateInput() call.
Assert.That(input.Locations.Select(loc => loc.Name), Is.EquivalentTo(new[]
{
selectedLocationOneName,
selectedLocationTwoName
}));
Assert.That(input.Segments.Select(segment => segment.Name), Is.EquivalentTo(new[]
{
selectedSegmentOneName,
selectedSegmentTwoName
}));
IEnumerable segmentWith2DProfile = input.Segments.Where(s => string.Equals(s.Name, selectedSegmentOneName) || string.Equals(s.Name, selectedSegmentTwoName));
IEnumerable probabilities = segmentWith2DProfile.SelectMany(p => p.SoilGeometryProbability);
Assert.That(probabilities.All(prob => prob.SoilProfileType == ConversionHelper.ConvertToInputSoilProfileType(SoilProfileType.SoilProfile2D)), Is.True);
Assert.That(input.SoilProfiles2D.Select(profile => profile.Name), Is.EquivalentTo(new[]
{
soilProfileName
}));
}
[Test]
public void GivenDamProjectWithInvalidLocationsWithoutScenariosWith2DProfiles_WhenCreatingInput_ThenOnlyValidLocationsSerializedAndLogsErrorMessage()
{
// Given
LogManager.Messages.Clear();
const string selectedLocationOneName = "SelectedLocationOne";
const string selectedSegmentOneName = "SelectedSegmentOne";
const string segmentOneSoilProfileName = "Profile2D 1.stix";
const string selectedLocationTwoName = "SelectedLocationTwo";
const string selectedSegmentTwoName = "SelectedSegmentTwo";
const string segmentTwoSoilProfileName = "Profile2D 2.stix"; // Soil profile also contains Soil 3 for its layers
// Add the locations with the segments
var dike = new Dike
{
MapForSoilGeometries2D = @"TestData\FillXMLInputFromDamUI",
SoilList = CreateSoilList(new[]
{
"Soil 1",
"Soil 2"
})
};
dike.Locations.AddRange(new[]
{
CreateSimpleLocationWithSoilProfile2DSegment(selectedLocationOneName, selectedSegmentOneName, segmentOneSoilProfileName),
// Soil profile will result in a read failure, because it does not exist.
// However, this will not be visible in the log, as it is not selected to be calculated.
CreateSimpleLocationWithSoilProfile2DSegment("LocationTwo", "Segment", "DoesNotExist.stix"),
CreateSimpleLocationWithSoilProfile2DSegment(selectedLocationTwoName, selectedSegmentTwoName, segmentTwoSoilProfileName)
});
var selectedLocations = new HashSet(new[]
{
selectedLocationOneName,
selectedLocationTwoName
});
// Create the project to serialize
var waterBoard = new WaterBoard
{
Dikes = new List
{
dike
}
};
var projectData = new DamProjectData();
FillAnalysisSpecification(projectData);
FillStabilityParameters(projectData);
DamProject.ProjectMap = ""; // Set the folder to be empty so that it runs in the current test directory
projectData.WaterBoard = waterBoard;
foreach (LocationJob locationJob in projectData.LocationJobs)
{
if (selectedLocations.Contains(locationJob.Name))
{
locationJob.Run = true;
}
}
// Preconditions
// Assert that only the selected calculations are present to verify that the unselected jobs:
// - Locations and segments do not end up in the input
// - Do not generate an error message in case something goes wrong.
Assert.That(projectData.SelectedLocationJobs.Select(job => job.Name), Is.EquivalentTo(selectedLocations));
// When
Input input = FillXmlInputFromDamUi.CreateInput(projectData);
// Then
// Note that the original test setup of DAMProject --> XML --> DAMProject does not
// work in this context, as there is NO field within DAMProject to contain the SoilProfile2D
// The only way to assert that the selected locations, segments and their profiles are present,
// is to verify the XMLInput objects that are generated by the CreateInput() call.
Assert.That(input.Locations.Select(loc => loc.Name), Is.EquivalentTo(new[]
{
selectedLocationOneName
}));
Assert.That(input.Segments.Select(segment => segment.Name), Is.EquivalentTo(new[]
{
selectedSegmentOneName
}));
Assert.That(input.SoilProfiles2D.Select(profile => profile.Name), Is.EquivalentTo(new[]
{
segmentOneSoilProfileName
}));
DamEngine.Io.XmlInput.Segment segmentWith2DProfile = input.Segments.Single(s => string.Equals(s.Name, selectedSegmentOneName));
Assert.That(segmentWith2DProfile.SoilGeometryProbability.All(prob => prob.SoilProfileType == ConversionHelper.ConvertToInputSoilProfileType(SoilProfileType.SoilProfile2D)), Is.True);
Assert.That(LogManager.Messages, Has.Count.EqualTo(1));
Assert.That(LogManager.Messages[0].Message,
new StartsWithConstraint($"Location '{selectedLocationTwoName}': The calculation failed with error message:"));
Assert.That(LogManager.Messages, Has.All.Property(nameof(LogMessage.MessageType)).EqualTo(LogMessageType.Error));
Assert.That(LogManager.Messages, Has.All.Property(nameof(LogMessage.Subject)).EqualTo(null));
}
[Test]
public void GivenDamProjectWithInvalidLocationsWithScenariosWith2DProfiles_WhenCreatingInput_ThenOnlyValidLocationsSerializedAndLogsErrorMessage()
{
// Given
LogManager.Messages.Clear();
// Add the locations with the segments
const string selectedLocationOneName = "SelectedLocationOne";
const string selectedSegmentOneName = "SelectedSegmentOne";
const string segmentOneSoilProfileName = "Profile2D 1.stix";
Location validLocation = CreateSimpleLocationWithSoilProfile2DSegment(selectedLocationOneName, selectedSegmentOneName, segmentOneSoilProfileName);
validLocation.Scenarios.AddRange(new[]
{
CreateValidScenario("ValidScenarioOne"),
CreateValidScenario("ValidScenarioTwo")
});
const string selectedLocationTwoName = "SelectedLocationTwo";
const string selectedSegmentTwoName = "SelectedSegmentTwo";
const string segmentTwoSoilProfileName = "DoesNotExist.stix";
Location invalidLocation = CreateSimpleLocationWithSoilProfile2DSegment(selectedLocationTwoName, selectedSegmentTwoName, segmentTwoSoilProfileName);
invalidLocation.Scenarios.AddRange(new[]
{
CreateValidScenario("InvalidScenarioOne"),
CreateValidScenario("InvalidScenarioTwo")
});
var dike = new Dike
{
MapForSoilGeometries2D = @"TestData\FillXMLInputFromDamUI",
SoilList = CreateSoilList(new[]
{
"Soil 1",
"Soil 2"
})
};
dike.Locations.AddRange(new[]
{
validLocation,
invalidLocation
});
// Create the project to serialize
var waterBoard = new WaterBoard
{
Dikes = new List
{
dike
}
};
var projectData = new DamProjectData();
FillAnalysisSpecification(projectData);
FillStabilityParameters(projectData);
DamProject.ProjectMap = ""; // Set the folder to be empty so that it runs in the current test directory
projectData.WaterBoard = waterBoard;
foreach (LocationJob locationJob in projectData.LocationJobs)
{
locationJob.Run = true;
}
// When
Input input = FillXmlInputFromDamUi.CreateInput(projectData);
// Then
// Note that the original test setup of DAMProject --> XML --> DAMProject does not
// work in this context, as there is NO field within DAMProject to contain the SoilProfile2D
// The only way to assert that the selected locations, segments and their profiles are present,
// is to verify the XMLInput objects that are generated by the CreateInput() call.
Assert.That(input.Locations.Select(loc => loc.Name), Is.EquivalentTo(new[]
{
selectedLocationOneName
}));
Assert.That(input.Segments.Select(segment => segment.Name), Is.EquivalentTo(new[]
{
selectedSegmentOneName
}));
Assert.That(input.SoilProfiles2D.Select(profile => profile.Name), Is.EquivalentTo(new[]
{
segmentOneSoilProfileName
}));
DamEngine.Io.XmlInput.Segment segmentWith2DProfile = input.Segments.Single(s => string.Equals(s.Name, selectedSegmentOneName));
Assert.That(segmentWith2DProfile.SoilGeometryProbability.All(prob => prob.SoilProfileType == ConversionHelper.ConvertToInputSoilProfileType(SoilProfileType.SoilProfile2D)), Is.True);
Assert.That(LogManager.Messages, Has.Count.EqualTo(2));
Assert.That(LogManager.Messages[0].Message,
new StartsWithConstraint($"Location '{selectedLocationTwoName}', design scenario 'InvalidScenarioOne': The calculation failed with error message:"));
Assert.That(LogManager.Messages[1].Message,
new StartsWithConstraint($"Location '{selectedLocationTwoName}', design scenario 'InvalidScenarioTwo': The calculation failed with error message:"));
Assert.That(LogManager.Messages, Has.All.Property(nameof(LogMessage.MessageType)).EqualTo(LogMessageType.Error));
Assert.That(LogManager.Messages, Has.All.Property(nameof(LogMessage.Subject)).EqualTo(null));
}
[Test]
[TestCase("location_12_2_1D1")] // Between "location_12" and "_2_1D1" there are 2 illegal characters (1F hex)
public void GivenDataSetContainingIllegalCharactersWhenWritingXmlThenRaiseExceptionWithClearMessage(string id)
{
// Given DataSet Containing Illegal Characters
DamProjectData expectedDamProjectData = CreateExampleDamProjectData();
Location location = expectedDamProjectData.WaterBoard.Dikes[0].Locations[0];
location.Name = id;
// When Writing Xml
Assert.That(() => FillXmlInputFromDamUi.CreateInput(expectedDamProjectData), Throws.InstanceOf().With.Message.EqualTo("Location has an invalid name location_12_2_1D1"));
}
[Test]
[TestCase("ABCDEFGHIJLMNOPQRSTUVWXYZ")]
[TestCase("A")]
[TestCase("Z")]
[TestCase("K")]
[TestCase("JUSTATEST")]
[TestCase("abcdefghijklmnopqrstuvwxyz")]
[TestCase("a")]
[TestCase("z")]
[TestCase("k")]
[TestCase("justatest")]
[TestCase("01234567879")]
[TestCase("0")]
[TestCase("9")]
[TestCase("5")]
[TestCase("!#$%&()*+,-./")]
[TestCase(":;<=>?@")]
[TestCase(@"[\]^_`")]
[TestCase("{|}~")]
[TestCase("!")]
public void GivenDataSetContainingIdWithLegalCharactersWhenWritingXmlThenSucceeds(string id)
{
// Given DataSet Containing Illegal Characters
DamProjectData expectedDamProjectData = CreateExampleDamProjectData();
Location location = expectedDamProjectData.WaterBoard.Dikes[0].Locations[0];
location.Name = id;
// When Writing Xml
Input input = FillXmlInputFromDamUi.CreateInput(expectedDamProjectData);
string xmlString = DamXmlSerialization.SaveInputAsXmlString(input);
// Then Raise Exception With Clear Message()
input = DamXmlSerialization.LoadInputFromXmlString(xmlString);
DamProjectData actualDamProjectData = FillDamUiFromXmlInput.CreateDamProjectData(input);
CompareDamProjectData(actualDamProjectData, expectedDamProjectData);
}
[Test]
public void RaiseExceptionWhenRiverLevelIsMissing()
{
// Given DataSet with undefined RiverLevel
DamProjectData damProjectData = CreateExampleDamProjectData();
Scenario scenario = damProjectData.WaterBoard.Dikes[0].Locations[0].Scenarios[0];
scenario.RiverLevel = null;
// When Writing Xml, Then Raise Exception With Clear Message
string expectedMessage = "Location 'Location 1', scenario '1' has no river level (Parameter 'RiverLevel')";
Assert.That(() => FillXmlInputFromDamUi.CreateInput(damProjectData), Throws.TypeOf(typeof(ArgumentNullException)).With.Message.EqualTo(expectedMessage));
}
[Test]
[TestCase(FailureMechanismSystemType.StabilityOutside, "Location 'Location 1', scenario '1' has no river level low")]
[TestCase(FailureMechanismSystemType.StabilityInside, "")]
[TestCase(FailureMechanismSystemType.Piping, "")]
public void RaiseExceptionWhenRiverLevelLowIsMissingForStabilityOutside(FailureMechanismSystemType failureMechanismSystemType, string expectedMessage)
{
// Given DataSet with undefined RiverLevelLow
DamProjectData damProjectData = CreateExampleDamProjectData();
Scenario scenario = damProjectData.WaterBoard.Dikes[0].Locations[0].Scenarios[0];
scenario.RiverLevelLow = null;
DamFailureMechanismeCalculationSpecification currentSpecification = damProjectData.DamProjectCalculationSpecification.CurrentSpecification;
currentSpecification.FailureMechanismSystemType = failureMechanismSystemType;
// When Writing Xml, Then Raise Exception With Clear Message in case of Stability Outside
if (expectedMessage != string.Empty)
{
Assert.That(() => FillXmlInputFromDamUi.CreateInput(damProjectData), Throws.TypeOf(typeof(ArgumentNullException)).With.Message.Contains(expectedMessage));
}
else
{
Assert.That(() => FillXmlInputFromDamUi.CreateInput(damProjectData), Throws.Nothing);
}
}
[Test]
public void RaiseExceptionWhenWaterBoardIsNotDefined()
{
// Given DataSet with undefined waterboard
var damProjectData = new DamProjectData();
damProjectData.WaterBoard = null;
// When Writing Xml, Then Raise Exception With Clear Message in case of Stability Outside
string expectedMessage = "No dike defined in this project (Parameter 'WaterBoard')";
Assert.That(() => FillXmlInputFromDamUi.CreateInput(damProjectData), Throws.TypeOf(typeof(ArgumentNullException)).With.Message.EqualTo(expectedMessage));
}
/// Compares the soil lists.
/// The object comparer does not handle NaN's correctly, therefore this method is created.
/// The actual soil list.
/// The expected soil list.
private void CompareSoilLists(SoilList actualSoilList, SoilList expectedSoilList)
{
const string errorMessage = "Actual and expected values of {0} are not equal";
foreach (Soil actualSoil in actualSoilList.Soils)
{
Soil expectedSoil = expectedSoilList.GetSoilByName(actualSoil.Name);
Assert.That(actualSoil.AbovePhreaticLevel, Is.EqualTo(expectedSoil.AbovePhreaticLevel), string.Format(errorMessage, "AbovePhreaticLevel"));
Assert.That(actualSoil.BelowPhreaticLevel, Is.EqualTo(expectedSoil.BelowPhreaticLevel), string.Format(errorMessage, "BelowPhreaticLevel"));
Assert.That(actualSoil.DryUnitWeight, Is.EqualTo(expectedSoil.DryUnitWeight), string.Format(errorMessage, "DryUnitWeight"));
Assert.That(actualSoil.BeddingAngle, Is.EqualTo(expectedSoil.BeddingAngle), string.Format(errorMessage, "BeddingAngle"));
Assert.That(actualSoil.DiameterD70, Is.EqualTo(expectedSoil.DiameterD70), string.Format(errorMessage, "DiameterD70"));
Assert.That(actualSoil.DiameterD90, Is.EqualTo(expectedSoil.DiameterD90), string.Format(errorMessage, "DiameterD90"));
Assert.That(actualSoil.PermeabKx, Is.EqualTo(expectedSoil.PermeabKx), string.Format(errorMessage, "PermeabKx"));
Assert.That(actualSoil.WhitesConstant, Is.EqualTo(expectedSoil.WhitesConstant), string.Format(errorMessage, "WhitesConstant"));
Assert.That(actualSoil.ShearStrengthModel, Is.EqualTo(expectedSoil.ShearStrengthModel), string.Format(errorMessage, "ShearStrengthModel"));
Assert.That(actualSoil.UseDefaultShearStrengthModel, Is.EqualTo(expectedSoil.UseDefaultShearStrengthModel), string.Format(errorMessage, "UseDefaultShearStrengthModel"));
Assert.That(actualSoil.Cohesion, Is.EqualTo(expectedSoil.Cohesion), string.Format(errorMessage, "Cohesion"));
Assert.That(actualSoil.FrictionAngle, Is.EqualTo(expectedSoil.FrictionAngle), string.Format(errorMessage, "FrictionAngle"));
Assert.That(actualSoil.OCR, Is.EqualTo(expectedSoil.OCR), string.Format(errorMessage, "OCR"));
Assert.That(actualSoil.RestSlope, Is.EqualTo(expectedSoil.RestSlope), string.Format(errorMessage, "RestSlope"));
Assert.That(actualSoil.DilatancyType, Is.EqualTo(expectedSoil.DilatancyType), string.Format(errorMessage, "DilatancyType"));
Assert.That(actualSoil.StrengthIncreaseExponent, Is.EqualTo(expectedSoil.StrengthIncreaseExponent), string.Format(errorMessage, "StrengthIncreaseExponent"));
Assert.That(actualSoil.RRatio, Is.EqualTo(expectedSoil.RRatio), string.Format(errorMessage, "RRatio"));
Assert.That(actualSoil.RatioCuPc, Is.EqualTo(expectedSoil.RatioCuPc), string.Format(errorMessage, "RatioCuPc"));
}
}
private static void CompareSoilProfiles2D(SoilProfile2D[] actual, SoilProfile2D[] expected)
{
var compare = new CompareLogic
{
Config =
{
MaxDifferences = 10
}
};
ComparisonResult result = compare.Compare(expected, actual);
Assert.Multiple(() =>
{
Assert.That(result.Differences, Is.Empty,
"Differences found read/write Soil Profile 2D object:" + result.DifferencesString);
// Check that the soil profile 2D used in the DamProjectData contains an inner loop (with 4 points)
Assert.That(actual[0].Layers2D[1].Surface.Innerloop, Has.Length.EqualTo(4));
});
}
private void CompareDamProjectData(DamProjectData actual, DamProjectData expected)
{
var compare = new CompareLogic
{
Config =
{
MaxDifferences = 10,
MembersToIgnore = new List
{
"SheetPilePoint",
"SheetPilePointX",
"SheetPilePointY",
"SheetPilePointZ",
"LocalXZSheetPilePoint",
"WaterBoardJob",
"LocationJobs",
"SelectedLocationJobs",
"PickSensors",
"MapForSoilGeometries2D",
"XSoilGeometry2DOrigin"
}
}
};
ComparisonResult result = compare.Compare(expected, actual);
Assert.That(result.Differences, Is.Empty,
"Differences found read/write Input object:" + result.DifferencesString);
}
#region CreateTestData
private Location CreateSimpleLocationWithSoilProfile2DSegment(string locationName,
string segmentName,
string soilProfile2DName)
{
var surfaceLine = new SurfaceLine2
{
Name = $"SurfaceLine - {locationName}"
};
surfaceLine.CharacteristicPoints.Geometry = surfaceLine.Geometry;
AddPointsToSurfaceLines(surfaceLine);
var random = new Random(21);
var segment = new Segment
{
Name = segmentName
};
segment.AddSoilGeometry2DProbability(soilProfile2DName, random.NextDouble(), null);
var location = new Location(locationName)
{
LocalXZSurfaceLine2 = surfaceLine,
Segment = segment,
DikeEmbankmentMaterial = "Soil 1"
};
return location;
}
private Location CreateSimpleLocationWithSoilProfile1DSegment(string locationName,
string segmentName,
SoilProfile1D soilProfile)
{
var surfaceLine = new SurfaceLine2
{
Name = $"SurfaceLine - {locationName}"
};
surfaceLine.CharacteristicPoints.Geometry = surfaceLine.Geometry;
AddPointsToSurfaceLines(surfaceLine);
var random = new Random(21);
var segment = new Segment
{
Name = segmentName
};
segment.AddSoilProfileProbability(soilProfile, random.NextDouble(), null);
var location = new Location(locationName)
{
LocalXZSurfaceLine2 = surfaceLine,
Segment = segment,
DikeEmbankmentMaterial = "Soil 1"
};
return location;
}
private static Scenario CreateValidScenario(string scenarioName)
{
var random = new Random(21);
return new Scenario
{
LocationScenarioID = scenarioName,
RiverLevel = random.NextDouble()
};
}
private DamProjectData CreateExampleDamProjectData()
{
var damProjectData = new DamProjectData();
DamProject.ProjectMap = ""; // Keep project map empty so that it runs in its current assembly group
FillAnalysisSpecification(damProjectData);
FillStabilityParameters(damProjectData);
damProjectData.WaterBoard = new WaterBoard();
damProjectData.WaterBoard.Dikes = new List();
damProjectData.WaterBoard.Dikes.Add(new Dike
{
MapForSoilGeometries2D = @"TestData\FillXMLInputFromDamUI"
});
damProjectData.MaxCalculationCores = 3;
Dike dike = damProjectData.WaterBoard.Dikes[0];
List surfaceLines = CreateSurfaceLines();
FillSoils(dike);
FillSoilProfiles1D(dike);
FillSegments(damProjectData);
AddLocations(dike, surfaceLines, damProjectData.WaterBoard.Segments);
foreach (LocationJob locationJob in damProjectData.LocationJobs)
{
locationJob.Run = true;
}
FillInputTimeSeries(damProjectData);
FillSensorData(damProjectData);
FillTrafficLoadDegreeOfConsolidation(dike);
return damProjectData;
}
private static void FillTrafficLoadDegreeOfConsolidation(Dike dike)
{
dike.TrafficLoadDegreeOfConsolidations = new List();
for (var i = 0; i < dike.SoilList.Soils.Count; i++)
{
var loadDegreeOfConsolidation = new TrafficLoadDegreeOfConsolidation
{
DegreeOfConsolidation = i * 3,
SoilName = dike.SoilList.Soils[i].Name
};
dike.TrafficLoadDegreeOfConsolidations.Add(loadDegreeOfConsolidation);
}
}
private void FillSensorData(DamProjectData damProjectData)
{
// Note: the properties SensorLocations, Sensors and SensorGroups of SensorData are automatically created
damProjectData.SensorData = new SensorData();
SensorData sensorData = damProjectData.SensorData;
var sensor1 = new Sensor
{
ID = 1,
Name = "Sensor 1",
RelativeLocation = 12.2,
Type = SensorType.WaterLevel,
PLLineMappings = new[]
{
PLLineType.PL1
}
};
sensorData.Sensors.Add(sensor1);
var sensor2 = new Sensor
{
ID = 2,
Name = "Sensor 2",
RelativeLocation = 24.2,
Type = SensorType.PolderLevel,
PLLineMappings = new[]
{
PLLineType.PL1
}
};
sensorData.Sensors.Add(sensor2);
var sensorGroup1 = new Group
{
ID = 1,
SensorArray = new[]
{
sensor1,
sensor2
}
};
sensorData.SensorGroups.Add(sensorGroup1);
var sensorLocation1 = new SensorLocation
{
Location = damProjectData.WaterBoard.Dikes[0].Locations[0],
Group = sensorGroup1,
SourceTypePl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData,
SourceTypePl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.LocationData,
SourceTypePl1WaterLevelAtPolder = DataSourceTypeSensors.Sensor,
SourceTypePl1WaterLevelAtRiver = DataSourceTypeSensors.Sensor,
SourceTypePl3 = DataSourceTypeSensors.Sensor,
SourceTypePl4 = DataSourceTypeSensors.Sensor,
SourceTypePl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.LocationData,
SourceTypePl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.LocationData
};
damProjectData.WaterBoard.Dikes[0].Locations[0].SensorLocation = sensorLocation1;
sensorData.SensorLocations.Add(sensorLocation1);
var sensor3 = new Sensor
{
ID = 3,
Name = "Sensor 3",
RelativeLocation = 8.8,
Type = SensorType.PiezometricHead,
PLLineMappings = new[]
{
PLLineType.PL3,
PLLineType.PL4
}
};
sensorData.Sensors.Add(sensor3);
var sensorGroup2 = new Group
{
ID = 2,
SensorArray = new[]
{
sensor3
}
};
sensorData.SensorGroups.Add(sensorGroup2);
var sensorLocation2 = new SensorLocation
{
Location = damProjectData.WaterBoard.Dikes[0].Locations[0],
Group = sensorGroup1,
SourceTypePl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData,
SourceTypePl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.LocationData,
SourceTypePl1WaterLevelAtPolder = DataSourceTypeSensors.Sensor,
SourceTypePl1WaterLevelAtRiver = DataSourceTypeSensors.Sensor,
SourceTypePl3 = DataSourceTypeSensors.Sensor,
SourceTypePl4 = DataSourceTypeSensors.Sensor,
SourceTypePl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.LocationData,
SourceTypePl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.LocationData
};
damProjectData.WaterBoard.Dikes[0].Locations[2].SensorLocation = sensorLocation2;
sensorData.SensorLocations.Add(sensorLocation2);
}
private void FillInputTimeSeries(DamProjectData damProjectData)
{
const int timeSeriesCount = 2;
const int timeEntriesCount = 3;
const string idWaterLevel = "WaterLevel";
const string idWaterPressure = "WaterPressure";
damProjectData.InputTimeSerieCollection = new TimeSerieCollection();
for (var i = 0; i < timeSeriesCount; i++)
{
var locationId = $"location{i}";
TimeSerie timeSerie = damProjectData.InputTimeSerieCollection.AddNewSeries(locationId);
timeSerie.ParameterId = (i % 2 == 0) ? idWaterLevel : idWaterPressure;
timeSerie.ForecastDateTime = DateTime.Now;
timeSerie.StartDateTime = new DateTime(2012, 12, 31);
timeSerie.EndDateTime = new DateTime(2012, 12, 31, 1, 0, 0);
timeSerie.MissVal = -9999.0;
for (var j = 0; j < timeEntriesCount; j++)
{
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2012, 12, 31, 1, j * 10, 0),
Value = j
});
}
}
}
private static void FillAnalysisSpecification(DamProjectData damProjectData)
{
damProjectData.DamProjectType = DamProjectType.Design;
damProjectData.DamProjectCalculationSpecification = new DamProjectCalculationSpecification();
DamProjectCalculationSpecification.SelectedAnalysisType = expectedAnalysisType;
var calculationSpecification = new DamFailureMechanismeCalculationSpecification
{
FailureMechanismSystemType = FailureMechanismSystemType.Piping,
CalculationModel = PipingModelType.Bligh
};
damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications.Add(calculationSpecification);
}
private static void FillStabilityParameters(DamProjectData damProjectData)
{
// Note: DamProjectCalculationSpecification created and filled by FillAnalysisSpecification
DamFailureMechanismeCalculationSpecification curspec = damProjectData.DamProjectCalculationSpecification.CurrentSpecification;
curspec.FailureMechanismeParamatersMStab = new FailureMechanismeParamatersMStab
{
MStabParameters = new MStabParameters
{
SearchMethod = StabilitySearchMethod.Grid,
SlipCircleDefinition = new SlipCircleDefinition
{
UpliftVanGridSizeDetermination = GridSizeDetermination.Specified,
BishopSearchAreaDetermination = GridSizeDetermination.Specified,
BishopGridHorizontalPointCount = 4,
BishopGridHorizontalPointDistance = 1.2,
BishopGridVerticalPointCount = 5,
BishopGridVerticalPointDistance = 1.1,
BishopTangentLinesDistance = 0.25,
UpliftVanLeftGridHorizontalPointCount = 6,
UpliftVanLeftGridHorizontalPointDistance = 0.7,
UpliftVanLeftGridVerticalPointCount = 3,
UpliftVanLeftGridVerticalPointDistance = 1.3,
UpliftVanRightGridHorizontalPointCount = 8,
UpliftVanRightGridHorizontalPointDistance = 1.76,
UpliftVanRightGridVerticalPointCount = 11,
UpliftVanRightGridVerticalPointDistance = 0.14,
UpliftVanTangentLinesDefinition = TangentLinesDefinition.OnBoundaryLines,
UpliftVanTangentLinesDistance = 0.01
}
}
};
}
private void FillSoils(Dike dike)
{
const int soilCount = 3;
dike.SoilList = new SoilList();
for (var i = 0; i < soilCount; i++)
{
var soil = new Soil
{
Name = $"Soil {i}"
};
soil.AbovePhreaticLevel = 7 + 0.1 * i;
soil.BelowPhreaticLevel = 8 + 0.1 * i;
soil.DiameterD70 = 19 + 0.1 * i;
soil.PermeabKx = 21 + 0.1 * i;
soil.ShearStrengthModel = ShearStrengthModel.CuCalculated;
soil.UseDefaultShearStrengthModel = false;
soil.Cohesion = 23 + 0.1 * i;
soil.FrictionAngle = 24 + 0.1 * i;
soil.OCR = 25 + 0.1 * i;
soil.StrengthIncreaseExponent = 28 + 0.1 * i;
soil.RatioCuPc = 29 + 0.1 * i;
dike.SoilList.Add(soil);
}
// Change 1 soil to ShearStrengthModel.StressTable (SigmaTauCurve)
Soil soilSigmaTauCurve = dike.SoilList.Soils[1];
soilSigmaTauCurve.ShearStrengthModel = ShearStrengthModel.StressTable;
soilSigmaTauCurve.StressTable = new StressCurve();
soilSigmaTauCurve.StressTable.SigmaTaus.Add(new SigmaTau
{
Sigma = 0.0,
Tau = 1.0
});
soilSigmaTauCurve.StressTable.SigmaTaus.Add(new SigmaTau
{
Sigma = 1.0,
Tau = 2.0
});
// Change 1 soil to ShearStrengthModel.SuTable
Soil soilSuTable = dike.SoilList.Soils[2];
soilSuTable.ShearStrengthModel = ShearStrengthModel.SuTable;
soilSuTable.SuTable = new SigmaSuCurve();
soilSuTable.SuTable.SigmaSus.Add(new SigmaSu()
{
Sigma = 0.0,
Su = 1.1
});
soilSuTable.SuTable.SigmaSus.Add(new SigmaSu()
{
Sigma = 1.1,
Su = 2.1
});
// Add dike embankment material
var dikeSoil = new Soil
{
Name = dikeEmbankmentMaterial,
UseDefaultShearStrengthModel = false
};
dike.SoilList.Add(dikeSoil);
// Add shoulder embankment materials
for (int i = 0; i < locationCount; i++)
{
var shoulderSoil = new Soil
{
Name = shoulderEmbankmentMaterial + (i + 1),
UseDefaultShearStrengthModel = false
};
dike.SoilList.Add(shoulderSoil);
}
}
private void AddLocations(Dike dike, List surfaceLines, IList segments)
{
for (var i = 0; i < locationCount; i++)
{
var location = new Location();
location.Name = "Location " + (i + 1);
location.XSoilGeometry2DOrigin = 1.0 * i + 0.01;
location.PLLineCreationMethod = (PLLineCreationMethod) i;
location.IntrusionVerticalWaterPressure = (IntrusionVerticalWaterPressureType) i;
location.DampingFactorPL4 = 1.0 * i + 0.12;
location.DampingFactorPL3 = 1.0 * i + 0.13;
location.PenetrationLength = 1.0 * i + 0.14;
location.SlopeDampingPiezometricHeightPolderSide = 1.0 * i + 0.19;
location.LocalXZSurfaceLine2 = surfaceLines[i];
location.Segment = segments[i % 2]; // alternate between the 2 available segments
for (var j = 0; j < 3; j++)
{
Scenario designScenario = FillDesignScenario(i, j);
location.Scenarios.Add(designScenario);
}
location.DikeEmbankmentMaterial = dikeEmbankmentMaterial;
location.StabilityZoneType = StabilityZoneType.NoZones;
location.ForbiddenZoneFactor = 10.0 * i + 0.42;
location.TrafficLoad = 10.0 * i + 0.44;
location.TL_DegreeOfConsolidation = 10.0 * i + 0.45;
location.RedesignDikeHeight = false;
location.RedesignDikeShoulder = false;
location.ShoulderEmbankmentMaterial = shoulderEmbankmentMaterial + (i + 1);
location.StabilityShoulderGrowSlope = 10.0 * i + 0.50;
location.StabilityShoulderGrowDeltaX = 10.0 * i + 0.51;
location.StabilitySlopeAdaptionDeltaX = 10.0 * i + 0.52;
location.SlopeAdaptionStartCotangent = 10.0 * i + 0.53;
location.SlopeAdaptionEndCotangent = 10.0 * i + 0.54;
location.SlopeAdaptionStepCotangent = 10.0 * i + 0.55;
location.UseNewDikeTopWidth = true;
location.UseNewDikeSlopeInside = true;
location.UseNewDikeSlopeOutside = true;
location.UseNewShoulderTopSlope = true;
location.UseNewShoulderBaseSlope = true;
location.UseNewMaxHeightShoulderAsFraction = true;
location.UseNewMinDistanceDikeToeStartDitch = true;
location.UseNewDitchDefinition = true;
location.NewDikeTopWidth = 10.0 * i + 0.56;
location.NewDikeSlopeInside = 10.0 * i + 0.57;
location.NewDikeSlopeOutside = 10.0 * i + 0.58;
location.NewShoulderTopSlope = 10.0 * i + 0.59;
location.NewShoulderBaseSlope = 10.0 * i + 0.60;
location.NewMaxHeightShoulderAsFraction = 10.0 * i + 0.61;
location.NewMinDistanceDikeToeStartDitch = 10.0 * i + 0.62;
location.UseNewDitchDefinition = true;
location.NewWidthDitchBottom = 10.0 * i + 0.63;
location.NewSlopeAngleDitch = 10.0 * i + 0.64;
location.NewDepthDitch = 10.0 * i + 0.65;
location.StabilityDesignMethod = StabilityDesignMethod.SlopeAdaptionBeforeShoulderAdaption;
dike.Locations.Add(location);
}
}
private static Scenario FillDesignScenario(int locationIndex, int designScenarioIndex)
{
int factor = locationIndex * designScenarioIndex;
return new Scenario
{
LocationScenarioID = (designScenarioIndex + 1).ToString(),
RiverLevel = 1.0 * factor + 0.51,
RiverLevelLow = 1.0 * factor + 0.52,
DikeTableHeight = 1.0 * factor + 0.53,
PlLineOffsetBelowDikeTopAtRiver = 1.0 * factor + 0.54,
PlLineOffsetBelowDikeTopAtPolder = 1.0 * factor + 0.55,
PlLineOffsetBelowShoulderBaseInside = 1.0 * factor + 0.56,
PlLineOffsetBelowDikeToeAtPolder = 1.0 * factor + 0.57,
PlLineOffsetBelowDikeCrestMiddle = 1.0 * factor + 0.58,
UsePlLineOffsetBelowDikeCrestMiddle = true,
PlLineOffsetFactorBelowShoulderCrest = 1.0 * factor + 0.59,
UsePlLineOffsetFactorBelowShoulderCrest = true,
HeadPl3 = 1.0 * factor + 0.60,
HeadPl4 = 1.0 * factor + 0.61,
UpliftCriterionStability = 1.0 * factor + 0.62,
UpliftCriterionPiping = 1.0 * factor + 0.63,
RequiredSafetyFactorStabilityInnerSlope = 1.0 * factor + 0.64,
RequiredSafetyFactorStabilityOuterSlope = 1.0 * factor + 0.65,
RequiredSafetyFactorPiping = 1.0 * factor + 0.66,
PolderLevel = 1.0 * factor + 0.67,
HeadPl2 = 1.0 * factor + 0.68
};
}
private List CreateSurfaceLines()
{
var surfaceLines = new List();
const int surfaceLineCount = 3;
for (var i = 0; i < surfaceLineCount; i++)
{
var surfaceLine = new SurfaceLine2();
surfaceLine.Name = $"SurfaceLine {i}";
surfaceLine.CharacteristicPoints.Geometry = surfaceLine.Geometry;
AddPointsToSurfaceLines(surfaceLine);
surfaceLines.Add(surfaceLine);
}
return surfaceLines;
}
private void AddPointsToSurfaceLines(SurfaceLine2 surfaceLine)
{
AddPointToSurfaceLine(surfaceLine, 0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside);
AddPointToSurfaceLine(surfaceLine, 2.0, 0.5, CharacteristicPointType.None);
AddPointToSurfaceLine(surfaceLine, 4.0, 0.0, CharacteristicPointType.DikeToeAtRiver);
AddPointToSurfaceLine(surfaceLine, 9.0, 5.0, CharacteristicPointType.DikeTopAtRiver);
AddPointToSurfaceLine(surfaceLine, 10.0, 5.2, CharacteristicPointType.None);
AddPointToSurfaceLine(surfaceLine, 13.0, 5.4, CharacteristicPointType.DikeTopAtPolder);
AddPointToSurfaceLine(surfaceLine, 18.0, 1.0, CharacteristicPointType.DikeToeAtPolder);
AddPointToSurfaceLine(surfaceLine, 24.0, 1.0, CharacteristicPointType.SurfaceLevelInside);
}
private void AddPointToSurfaceLine(SurfaceLine2 surfaceLine, double xCoordinate, double zCoordinate, CharacteristicPointType characteristicPointType)
{
var geometryPoint = new GeometryPoint
{
X = xCoordinate,
Y = 0.0,
Z = zCoordinate
};
surfaceLine.AddCharacteristicPoint(geometryPoint, characteristicPointType);
}
private static void FillSoilProfiles1D(Dike dike)
{
dike.SoilProfiles = new List();
var profile = new SoilProfile1D
{
Name = "Profile1D 1",
BottomLevel = -21.12
};
const int layerCount = 3;
for (var j = 0; j < layerCount; j++)
{
var layer = new SoilLayer1D
{
Id = "L" + j,
Soil = dike.SoilList.Soils[j],
TopLevel = 1 * -j
};
if (j < 2)
{
layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Automatic;
layer.IsAquifer = false;
}
else
{
layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Hydrostatic;
layer.IsAquifer = true;
}
profile.Layers.Add(layer);
}
dike.SoilProfiles.Add(profile);
}
private static void FillSegments(DamProjectData damProjectData)
{
const int segmentCount = 2;
Dike dike = damProjectData.WaterBoard.Dikes[0];
for (var i = 0; i < segmentCount; i++)
{
var segment = new Segment
{
Name = "Segment " + i
};
var soilProfileProbability = new SoilGeometryProbability();
if (i == 0)
{
soilProfileProbability.SegmentFailureMechanismType = FailureMechanismSystemType.StabilityInside;
soilProfileProbability.SoilGeometry2DName = $"Profile2D 1"; // Soil profile with inner loop
}
else
{
soilProfileProbability.SegmentFailureMechanismType = FailureMechanismSystemType.Piping;
string soilProfile1DName = "Profile1D 1";
soilProfileProbability.SoilProfile = FillDamUiFromXmlInput.FindSoilProfile1DByName(dike.SoilProfiles,
soilProfile1DName);
}
soilProfileProbability.Probability = 0.003 * (i + 1);
segment.SoilProfileProbabilities.Add(soilProfileProbability);
damProjectData.WaterBoard.Segments.Add(segment);
}
}
private static SoilList CreateSoilList(IEnumerable soilNames)
{
var soilList = new SoilList();
foreach (string soilName in soilNames)
{
var soilToBeAdded = new Soil
{
Name = soilName
};
soilList.Add(soilToBeAdded);
}
return soilList;
}
#endregion CreateTestData
}
}