// 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.DamEngineIo;
using Deltares.Geometry;
using Deltares.Geotechnics.Soils;
using Deltares.Standard.Extensions;
using NUnit.Framework;
using XMLSoilProfile2D = Deltares.DamEngine.Io.XmlInput.SoilProfile2D;
using XMLSoilLayer2D = Deltares.DamEngine.Io.XmlInput.SoilProfile2DLayer2D;
using XMLSoilLayer2DSurface = Deltares.DamEngine.Io.XmlInput.SoilProfile2DLayer2DSurface;
using XMLSurfaceOuterPoint = Deltares.DamEngine.Io.XmlInput.SoilProfile2DLayer2DSurfaceOuterPoint;
using XMLSurfaceInnerPoint = Deltares.DamEngine.Io.XmlInput.SoilProfile2DLayer2DSurfaceInnerPoint;
namespace Deltares.Dam.Tests.DamEngineIo
{
[TestFixture]
public class XmlSoilProfile2DConverterTest
{
[Test]
public void Convert_SoilProfileNull_ThrowsArgumentNullException()
{
// Call
TestDelegate call = () => XmlSoilProfile2DConverter.Convert(null);
// Assert
Assert.That(call, Throws.TypeOf()
.With.Property(nameof(ArgumentNullException.ParamName))
.EqualTo("soilProfile"));
}
///
/// -------------------------------------------------------------
/// Layer Two
/// |----------------------------------------------------|
/// | |
/// | |
/// | |
/// |----------------------------------------------------|
///
/// -------------------------------------------------------------
/// Layer one
///
///
///
/// -------------------------------------------------------------
///
[Test]
[TestCase(true, false)]
[TestCase(false, true)]
public void Convert_WithValidArgument_ReturnsExpectedSoilProfile2D(bool isLayerOneAquifer, bool isLayerTwoAquifer)
{
// Setup
var layerOne = new SoilLayer2D
{
Name = "LayerOne",
IsAquifer = isLayerOneAquifer,
GeometrySurface = new GeometrySurface(),
WaterpressureInterpolationModel = WaterpressureInterpolationModel.Automatic
};
layerOne.GeometrySurface.OuterLoop = CreateLoop(new GeometryPoint(0, 0, -15),
new GeometryPoint(10, 0, -15),
new GeometryPoint(0, 0, -10),
new GeometryPoint(10, 0, -10));
var layerTwo = new SoilLayer2D
{
Name = "LayerTwo",
IsAquifer = isLayerTwoAquifer,
GeometrySurface = new GeometrySurface(),
WaterpressureInterpolationModel = WaterpressureInterpolationModel.Hydrostatic
};
layerTwo.GeometrySurface.InnerLoops.AddRange(new[]
{
CreateLoop(new GeometryPoint(6, 0, -4),
new GeometryPoint(9, 0, -4),
new GeometryPoint(6, 0, -1),
new GeometryPoint(9, 0, -1))
});
layerTwo.GeometrySurface.OuterLoop = CreateLoop(new GeometryPoint(0, 0, -10),
new GeometryPoint(10, 0, -10),
new GeometryPoint(0, 0, 0),
new GeometryPoint(10, 0, 0));
var soilProfile = new SoilProfile2D
{
Name = "SoilProfile2D"
};
soilProfile.Surfaces.Add(layerOne);
soilProfile.Surfaces.Add(layerTwo);
// Call
XMLSoilProfile2D convertedProfile = XmlSoilProfile2DConverter.Convert(soilProfile);
Assert.Multiple(() =>
{
// Assert
Assert.That(convertedProfile.Name, Is.SameAs(soilProfile.Name));
Assert.That(convertedProfile.PreconsolidationStresses, Is.Empty); // Don't do anything with preconsolidation stresses yet
});
int nrOfExpectedSoilLayers = soilProfile.Surfaces.Count;
Assert.That(convertedProfile.Layers2D, Has.Length.EqualTo(nrOfExpectedSoilLayers));
for (var i = 0; i < nrOfExpectedSoilLayers; i++)
{
AssertLayer(soilProfile.Surfaces[i], convertedProfile.Layers2D[i]);
}
}
[Test]
public void Convert_SoilProfileContainsSoilLayerWithTwoInnerLoops_ThrowsConversionException()
{
// Setup
const string invalidLayerName = "invalidLayer";
var invalidLayer = new SoilLayer2D
{
Name = invalidLayerName,
IsAquifer = true,
GeometrySurface = new GeometrySurface()
};
invalidLayer.GeometrySurface.InnerLoops.AddRange(new[]
{
CreateLoop(new GeometryPoint(6, 0, -9),
new GeometryPoint(9, 0, -9),
new GeometryPoint(6, 0, -6),
new GeometryPoint(9, 0, -6)),
CreateLoop(new GeometryPoint(1, 0, -9),
new GeometryPoint(4, 0, -9),
new GeometryPoint(1, 0, -6),
new GeometryPoint(4, 0, -6))
});
invalidLayer.GeometrySurface.OuterLoop = CreateLoop(new GeometryPoint(0, 0, -10),
new GeometryPoint(10, 0, -10),
new GeometryPoint(0, 0, -5),
new GeometryPoint(10, 0, -5));
var soilProfile = new SoilProfile2D
{
Name = "SoilProfile2D"
};
soilProfile.Surfaces.Add(invalidLayer);
// Call
TestDelegate call = () => XmlSoilProfile2DConverter.Convert(soilProfile);
// Assert
Assert.That(call, Throws.Exception.TypeOf()
.With.Message.EqualTo("No soil assigned contains more than 1 inner loop."));
}
private static void AssertLayer(SoilLayer2D soilLayer, XMLSoilLayer2D convertedSoilLayer)
{
Assert.That(convertedSoilLayer.SoilName, Is.EqualTo(soilLayer.Name));
Assert.That(convertedSoilLayer.IsAquifer, Is.EqualTo(soilLayer.IsAquifer));
int expectedModel = ConversionHelper.ConvertToInputWaterpressureInterpolationModel(soilLayer.WaterpressureInterpolationModel);
Assert.That(convertedSoilLayer.WaterpressureInterpolationModel, Is.EqualTo(expectedModel));
AssertSurface(soilLayer.GeometrySurface, convertedSoilLayer.Surface);
}
private static void AssertSurface(GeometrySurface surface, XMLSoilLayer2DSurface convertedSurface)
{
IList outerLoopPoints = surface.OuterLoop.Points;
int nrOfExpectedOuterLoopPoints = outerLoopPoints.Count;
XMLSurfaceOuterPoint[] convertedOuterLoop = convertedSurface.OuterLoop;
Assert.That(convertedOuterLoop, Has.Length.EqualTo(nrOfExpectedOuterLoopPoints));
for (var i = 0; i < nrOfExpectedOuterLoopPoints; i++)
{
AssertPoint(outerLoopPoints[i], convertedOuterLoop[i]);
}
// Current XSD supports only ONE innerloop
GeometryLoop innerLoop = surface.InnerLoops.FirstOrDefault();
XMLSurfaceInnerPoint[] convertedInnerLoop = convertedSurface.Innerloop;
if (innerLoop == null)
{
Assert.That(convertedInnerLoop, Is.Empty);
return;
}
IList innerLoopPoints = innerLoop.Points;
int nrOfExpectedInnerLoopPoints = innerLoopPoints.Count;
Assert.That(convertedInnerLoop, Has.Length.EqualTo(nrOfExpectedInnerLoopPoints));
for (var i = 0; i < nrOfExpectedInnerLoopPoints; i++)
{
AssertPoint(innerLoopPoints[i], convertedInnerLoop[i]);
}
}
private static void AssertPoint(GeometryPoint point, XMLSurfaceOuterPoint convertedPoint)
{
Assert.That(convertedPoint.X, Is.EqualTo(point.X));
Assert.That(convertedPoint.Z, Is.EqualTo(point.Z));
}
private static void AssertPoint(GeometryPoint point, XMLSurfaceInnerPoint convertedPoint)
{
Assert.That(convertedPoint.X, Is.EqualTo(point.X));
Assert.That(convertedPoint.Z, Is.EqualTo(point.Z));
}
private static GeometryLoop CreateLoop(GeometryPoint bottomLeftPoint,
GeometryPoint bottomRightPoint,
GeometryPoint topLeftPoint,
GeometryPoint topRightPoint)
{
var loop = new GeometryLoop();
loop.CurveList.AddRange(new[]
{
new GeometryCurve(bottomLeftPoint, bottomRightPoint),
new GeometryCurve(bottomLeftPoint, topLeftPoint),
new GeometryCurve(topLeftPoint, topRightPoint),
new GeometryCurve(bottomRightPoint, topRightPoint)
});
return loop;
}
}
}