// Copyright (C) Stichting Deltares 2017. 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;
using System.Collections.Generic;
using Deltares.DamEngine.Data.Design;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.Geometry;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Io;
using Deltares.DamEngine.Io.XmlInput;
using KellermanSoftware.CompareNetObjects;
using NUnit.Framework;
using Segment = Deltares.DamEngine.Data.General.Segment;
using Soil = Deltares.DamEngine.Data.Geotechnics.Soil;
using SoilProfile1D = Deltares.DamEngine.Data.Geotechnics.SoilProfile1D;
using SoilProfile2D = Deltares.DamEngine.Data.Geotechnics.SoilProfile2D;
namespace Deltares.DamEngine.Interface.Tests
{
[TestFixture]
public class FillDamFromXmlInputTests
{
[Test]
public void CanWriteAndReadDamProjectDataToXml()
{
const string inputFilename = "InputFile.xml";
DamProjectData expectedDamProjectData = CreateExampleDamProjectData();
Input input = FillXmlInputFromDam.CreateInput(expectedDamProjectData);
DamXmlSerialization.SaveInputAsXmlFile(inputFilename, input);
input = DamXmlSerialization.LoadInputFromXmlFile(inputFilename);
DamProjectData actualDamProjectData = FillDamFromXmlInput.CreateDamProjectData(input);
CompareDamProjectData(actualDamProjectData, expectedDamProjectData);
}
[Test]
public void CanWriteAndReadDamProjectDataToXmlString()
{
string xmlString;
DamProjectData expectedDamProjectData = CreateExampleDamProjectData();
Input input = FillXmlInputFromDam.CreateInput(expectedDamProjectData);
xmlString = DamXmlSerialization.SaveInputAsXmlString(input);
input = DamXmlSerialization.LoadInputFromXmlString(xmlString);
DamProjectData actualDamProjectData = FillDamFromXmlInput.CreateDamProjectData(input);
CompareDamProjectData(actualDamProjectData, expectedDamProjectData);
}
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 DamProjectData CreateExampleDamProjectData()
{
var damProjectData = new DamProjectData();
damProjectData.DamProjectType = DamProjectType.Design;
damProjectData.Dike = new Dike();
Dike dike = damProjectData.Dike;
FillSurfaceLines(dike);
FillSoils(dike);
FillLocations(dike);
FillSoilProfiles1D(dike);
FillSoilProfiles2D(dike);
FillSegments(damProjectData);
return damProjectData;
}
private void FillSoils(Dike dike)
{
const int soilCount = 3;
dike.SoilList = new SoilList();
for (int i = 0; i < soilCount; i++)
{
Soil soil = new Soil() {Name = String.Format("Soil {0}", i)};
//soil.SoilType = SoilType.Loam;
//soil.AbovePhreaticLevel = 10 + 0.1 * i;
//soil.BelowPhreaticLevel = 10 + 0.1 * i;
//soil.DryUnitWeight = 10 + 0.1 * i;
//soil.ShearStrengthModel = ShearStrengthModel.CuMeasured;
//soil.Cohesion = 10 + 0.1 * i;
//soil.CuBottom = 11 + 0.1 * i;
//soil.CuTop = 12 + 0.1 * i;
//soil.DilatancyType = DilatancyType.Zero;
//soil.FrictionAngle = 13 + 0.1 * i;
//soil.Ocr = 14 + 0.1 * i;
//soil.PoP = 15 + 0.1 * i;
//soil.RatioCuPc = 16 + 0.1 * i;
//soil.StrengthIncreaseExponent = 17 + 0.1 * i;
//soil.UsePop = true;
soil.BeddingAngle = 18 + 0.1 * i;
soil.DiameterD70 = 19 + 0.1 * i;
soil.DiameterD90 = 20 + 0.1 * i;
soil.PermeabKx = 21 + 0.1 * i;
soil.WhitesConstant = 22 + 0.1 * i;
dike.SoilList.Add(soil);
}
}
private void FillSurfaceLines(Dike dike)
{
const int surfaceLineCount = 3;
for (int i = 0; i < surfaceLineCount; i++)
{
var surfaceLine = new SurfaceLine2();
surfaceLine.Name = String.Format("SurfaceLine {0}", i);
surfaceLine.CharacteristicPoints.Geometry = surfaceLine.Geometry;
AddPointsToSurfaceLines(surfaceLine);
dike.SurfaceLines2.Add(surfaceLine);
}
}
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 static void FillLocations(Dike dike)
{
const int locationCount = 3;
for (int i = 0; i < locationCount; i++)
{
var location = new Data.General.Location();
location.ModelParametersForPLLines.PLLineCreationMethod = (PLLineCreationMethod) i;
location.IntrusionVerticalWaterPressure = (IntrusionVerticalWaterPressureType) i;
location.PolderLevel = 1.0 * i + 0.11;
location.ModelParametersForPLLines.DampingFactorPL4 = 1.0 * i + 0.12;
location.ModelParametersForPLLines.DampingFactorPL3 = 1.0 * i + 0.13;
location.ModelParametersForPLLines.PenetrationLength = 1.0 * i + 0.14;
location.PlLineOffsetBelowDikeCrestMiddle = 1.0 * i + 0.15;
location.UsePlLineOffsetFactorBelowShoulderCrest = true;
location.PlLineOffsetFactorBelowShoulderCrest = 1.0 * i + 0.16;
location.PlLineOffsetDryBelowDikeCrestMiddle = 1.0 * i + 0.17;
location.UsePlLineOffsetDryFactorBelowShoulderCrest = true;
location.PlLineOffsetDryFactorBelowShoulderCrest = 1.0 * i + 0.18;
location.SlopeDampingPiezometricHeightPolderSide = 1.0 * i + 0.19;
location.PlLineOffsetBelowDikeTopAtRiver = 1.0 * i + 0.20;
location.PlLineOffsetBelowDikeTopAtPolder = 1.0 * i + 0.21;
location.PlLineOffsetBelowShoulderBaseInside = 1.0 * i + 0.22;
location.PlLineOffsetBelowDikeToeAtPolder = 1.0 * i + 0.23;
location.HeadPl2 = 1.0 * i + 0.24;
location.HeadPl3 = 1.0 * i + 0.25;
location.HeadPl4 = 1.0 * i + 0.21;
location.SurfaceLine2 = dike.SurfaceLines2[i];
for (int j = 0; j < 3; j++)
{
var designScenario = FillDesignScenario((i +1) * (j + 1)); // The parameter factor is used to create unique data for the design scenarios
location.Scenarios.Add(designScenario);
}
dike.Locations.Add(location);
}
}
private static void FillSoilProfiles1D(Dike dike)
{
dike.SoilProfiles = new List();
const int profilesCount = 2;
for (int i = 0; i < profilesCount; i++)
{
var profile = new SoilProfile1D();
profile.Name = "Profile1D " + (i + 1).ToString();
profile.BottomLevel = -21.12 * (i + 1);
const int layerCount = 3;
for (int j = 0; j < layerCount; j++)
{
var layer = new SoilLayer1D
{
Name = "Layer" + (j + 1).ToString(),
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 DesignScenario FillDesignScenario(int factor)
{
var designScenario = new DesignScenario();
designScenario.RiverLevel = 1.0 * factor + 0.51;
designScenario.RiverLevelLow = 1.0 * factor + 0.52;
designScenario.DikeTableHeight = 1.0 * factor + 0.53;
designScenario.PlLineOffsetBelowDikeTopAtRiver = 1.0 * factor + 0.54;
designScenario.PlLineOffsetBelowDikeTopAtPolder = 1.0 * factor + 0.55;
designScenario.PlLineOffsetBelowShoulderBaseInside = 1.0 * factor + 0.56;
designScenario.PlLineOffsetBelowDikeToeAtPolder = 1.0 * factor + 0.57;
designScenario.PlLineOffsetBelowDikeCrestMiddle = 1.0 * factor + 0.58;
designScenario.UsePlLineOffsetBelowDikeCrestMiddle = true;
designScenario.PlLineOffsetFactorBelowShoulderCrest = 1.0 * factor + 0.59;
designScenario.UsePlLineOffsetFactorBelowShoulderCrest = true;
designScenario.HeadPl3 = 1.0 * factor + 0.60;
designScenario.HeadPl4 = 1.0 * factor + 0.61;
designScenario.UpliftCriterionStability = 1.0 * factor + 0.62;
designScenario.UpliftCriterionPiping = 1.0 * factor + 0.63;
designScenario.RequiredSafetyFactorStabilityInnerSlope = 1.0 * factor + 0.64;
designScenario.RequiredSafetyFactorStabilityOuterSlope = 1.0 * factor + 0.65;
designScenario.RequiredSafetyFactorPiping = 1.0 * factor + 0.66;
return designScenario;
}
private static void FillSoilProfiles2D(Dike dike)
{
dike.SoilProfiles2D = new List();
const int profilesCount = 2;
for (int i = 0; i < profilesCount; i++)
{
var profile = new SoilProfile2D
{
Name = "Profile2D " + (i + 1).ToString()
};
const int preConCount = 2;
for (int j = 0; j < preConCount; j++)
{
var preCon = new PreConsolidationStress
{
Name = "Precon " + (j + 1).ToString(),
StressValue = 3.33 * (i + 1) * (j + 1),
X = 12.3 * (i + 1) * (j + 1),
Z = 0.3 * (-i - 1) * (j + 1)
};
profile.PreconsolidationStresses.Add(preCon);
}
const int layerCount = 3;
for (int j = 0; j < layerCount; j++)
{
var layer = new SoilLayer2D
{
Name = "Layer" + (j + 1).ToString(),
Soil = dike.SoilList.Soils[j]
};
if (j < 2)
{
layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Automatic;
layer.IsAquifer = false;
}
else
{
layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Hydrostatic;
layer.IsAquifer = true;
}
layer.GeometrySurface = new GeometrySurface();
var outerLoop = new GeometryLoop();
outerLoop.Points.Add((new GeometryPoint(0, 0)));
outerLoop.Points.Add((new GeometryPoint(0, 10)));
outerLoop.Points.Add((new GeometryPoint(10, 10)));
layer.GeometrySurface.OuterLoop = outerLoop;
var innerloop = new GeometryLoop();
innerloop.Points.Add((new GeometryPoint(1, 1)));
innerloop.Points.Add((new GeometryPoint(1, 9)));
innerloop.Points.Add((new GeometryPoint(9, 9)));
layer.GeometrySurface.InnerLoops.Add(innerloop);
profile.Surfaces.Add(layer);
}
dike.SoilProfiles2D.Add(profile);
}
}
private static void FillSegments(DamProjectData damProjectData)
{
var segmentCount = 2;
for (int i = 0; i < segmentCount; i++)
{
var segment = new Segment();
segment.Name = "Segment " + i.ToString();
var soilProfileProbability = new SoilGeometryProbability();
if (i == 0)
{
soilProfileProbability.SegmentFailureMechanismType = FailureMechanismSystemType.StabilityInside;
soilProfileProbability.SoilGeometry2DName = "Profile2D " + (i + 1).ToString();
}
else
{
soilProfileProbability.SegmentFailureMechanismType = FailureMechanismSystemType.Piping;
soilProfileProbability.SoilGeometry1DName = "Profile1D " + (i + 1).ToString();
}
soilProfileProbability.Probability = 0.003 * (i + 1);
segment.SoilProfileProbabilities.Add(soilProfileProbability);
damProjectData.Segments.Add(segment);
}
}
private void CompareDamProjectData(DamProjectData actual, DamProjectData expected)
{
var compare = new CompareLogic { Config = { MaxDifferences = 100 } };
var result = compare.Compare(expected, actual);
Assert.AreEqual(0, result.Differences.Count, "Differences found read/write Input object");
}
}
}