// Copyright (C) Stichting Deltares 2021. 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 System.Linq;
using Deltares.DamEngine.Data.Geometry;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard;
using NUnit.Framework;
namespace Deltares.DamEngine.Data.Tests.Geotechnics
{
[TestFixture]
public class SoilSurfaceProfileTests
{
[Test]
public void ConvertToSoilProfile2D_WithSurfaceLineFullyAboveSoilLayers_ReturnsExpectedSoilProfile2D()
{
// Setup
const string bottomLayerName = "BottomLayer";
const string middleLayerName = "MiddleLayer";
const string topLayerName = "TopLayer";
SoilLayer1D bottomLayer = CreateSoilLayer(-5, bottomLayerName);
SoilLayer1D middleLayer = CreateSoilLayer(-2, middleLayerName);
var profile = new SoilProfile1D
{
BottomLevel = -10
};
profile.Layers.Add(bottomLayer);
profile.Layers.Add(middleLayer);
SurfaceLine2 surfaceLine = CreateSurfaceLine(new[]
{
new GeometryPoint(0, 0),
new GeometryPoint(5, 10),
new GeometryPoint(10, 10)
});
var soilSurfaceProfile = new SoilSurfaceProfile
{
SoilProfile = profile,
SurfaceLine2 = surfaceLine,
DikeEmbankmentMaterial = new Soil
{
Name = topLayerName
}
};
// Call
SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D();
// Assert
var soilLayer2Ds = soilProfile2D.Surfaces;
Assert.That(soilLayer2Ds, Has.Count.EqualTo(3));
SoilLayer2D topSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, topLayerName));
AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, topSoilLayer2D);
AssertGeometry(new []
{
new GeometryCurve(new Point2D(0, 0), new Point2D(5, 10)),
new GeometryCurve(new Point2D(5, 10), new Point2D(10, 10)),
new GeometryCurve(new Point2D(10, 10), new Point2D(10, -2)),
new GeometryCurve(new Point2D(10, -2), new Point2D(5, -2)),
new GeometryCurve(new Point2D(5, -2), new Point2D(0, -2)),
new GeometryCurve(new Point2D(0, -2), new Point2D(0, 0))
}, topSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
SoilLayer2D middleSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName));
AssertSoilLayerProperties(middleLayer, middleSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -2), new Point2D(5, -2)),
new GeometryCurve(new Point2D(5, -2), new Point2D(10, -2)),
new GeometryCurve(new Point2D(10, -2), new Point2D(10, -5)),
new GeometryCurve(new Point2D(10, -5), new Point2D(5, -5)),
new GeometryCurve(new Point2D(5, -5), new Point2D(0, -5)),
new GeometryCurve(new Point2D(0, -5), new Point2D(0, -2))
}, middleSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
SoilLayer2D bottomSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName));
AssertSoilLayerProperties(bottomLayer, bottomSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -5), new Point2D(5, -5)),
new GeometryCurve(new Point2D(5, -5), new Point2D(10, -5)),
new GeometryCurve(new Point2D(10, -5), new Point2D(10, -10)),
new GeometryCurve(new Point2D(10, -10), new Point2D(5, -10)),
new GeometryCurve(new Point2D(5, -10), new Point2D(0, -10)),
new GeometryCurve(new Point2D(0, -10), new Point2D(0, -5))
}, bottomSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
}
[Test]
public void ConvertToSoilProfile2D_WithLayerFullyAboveSurfaceLine_ReturnsExpectedSoilProfile2D()
{
// Setup
const string bottomLayerName = "BottomLayer";
const string middleLayerName = "MiddleLayer";
const string topLayerName = "TopLayer";
SoilLayer1D irrelevantLayer = CreateSoilLayer(0, "Does not matter");
SoilLayer1D bottomLayer = CreateSoilLayer(-5, bottomLayerName);
SoilLayer1D middleLayer = CreateSoilLayer(-2, middleLayerName);
var profile = new SoilProfile1D
{
BottomLevel = -10
};
profile.Layers.Add(bottomLayer);
profile.Layers.Add(middleLayer);
profile.Layers.Add(irrelevantLayer);
SurfaceLine2 surfaceLine = CreateSurfaceLine(new[]
{
new GeometryPoint(0, -5),
new GeometryPoint(5, -3),
new GeometryPoint(10, -5)
});
var soilSurfaceProfile = new SoilSurfaceProfile
{
SoilProfile = profile,
SurfaceLine2 = surfaceLine,
DikeEmbankmentMaterial = new Soil
{
Name = topLayerName
}
};
// Call
SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D();
// Assert
var soilLayer2Ds = soilProfile2D.Surfaces;
Assert.That(soilLayer2Ds, Has.Count.EqualTo(2));
SoilLayer2D middleSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName));
AssertSoilLayerProperties(middleLayer, middleSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -5), new Point2D(5, -3)),
new GeometryCurve(new Point2D(5, -3), new Point2D(10, -5)),
new GeometryCurve(new Point2D(10, -5), new Point2D(5, -5)),
new GeometryCurve(new Point2D(5, -5), new Point2D(0, -5))
}, middleSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
SoilLayer2D bottomSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName));
AssertSoilLayerProperties(bottomLayer, bottomSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -5), new Point2D(5, -5)),
new GeometryCurve(new Point2D(5, -5), new Point2D(10, -5)),
new GeometryCurve(new Point2D(10, -5), new Point2D(10, -10)),
new GeometryCurve(new Point2D(10, -10), new Point2D(5, -10)),
new GeometryCurve(new Point2D(5, -10), new Point2D(0, -10)),
new GeometryCurve(new Point2D(0, -10), new Point2D(0, -5))
}, bottomSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
}
[Test]
public void ConvertToSoilProfile2D_WithSurfaceLineFullyEnvelopedByTopSoilLayer_ReturnsExpectedSoilProfile2D()
{
// Setup
const string bottomLayerName = "BottomLayer";
const string middleLayerName = "MiddleLayer";
const string topLayerName = "TopLayer";
SoilLayer1D bottomLayer = CreateSoilLayer(-5, bottomLayerName);
SoilLayer1D middleLayer = CreateSoilLayer(-2, middleLayerName);
var profile = new SoilProfile1D();
profile.Layers.Add(bottomLayer);
profile.Layers.Add(middleLayer);
profile.BottomLevel = -10;
SurfaceLine2 surfaceLine = CreateSurfaceLine(new[]
{
new GeometryPoint(0, -4),
new GeometryPoint(5, -2.5),
new GeometryPoint(10, -2.5)
});
var soilSurfaceProfile = new SoilSurfaceProfile
{
SoilProfile = profile,
SurfaceLine2 = surfaceLine,
DikeEmbankmentMaterial = new Soil
{
Name = topLayerName
}
};
// Call
SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D();
// Assert
var soilLayer2Ds = soilProfile2D.Surfaces;
Assert.That(soilLayer2Ds, Has.Count.EqualTo(2));
SoilLayer2D middleLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName));
AssertSoilLayerProperties(middleLayer, middleLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -4), new Point2D(5, -2.5)),
new GeometryCurve(new Point2D(5, -2.5), new Point2D(10, -2.5)),
new GeometryCurve(new Point2D(10, -2.5), new Point2D(10, -5)),
new GeometryCurve(new Point2D(10, -5), new Point2D(5, -5)),
new GeometryCurve(new Point2D(5, -5), new Point2D(0, -5)),
new GeometryCurve(new Point2D(0, -5), new Point2D(0, -4))
}, middleLayer2D.GeometrySurface.OuterLoop.CurveList);
SoilLayer2D bottomLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName));
AssertSoilLayerProperties(bottomLayer, bottomLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -5), new Point2D(5, -5)),
new GeometryCurve(new Point2D(5, -5), new Point2D(10, -5)),
new GeometryCurve(new Point2D(10, -5), new Point2D(10, -10)),
new GeometryCurve(new Point2D(10, -10), new Point2D(5, -10)),
new GeometryCurve(new Point2D(5, -10), new Point2D(0, -10)),
new GeometryCurve(new Point2D(0, -10), new Point2D(0, -5))
}, bottomLayer2D.GeometrySurface.OuterLoop.CurveList);
}
[Test]
public void ConvertToSoilProfile2D_WithSurfaceLinePartiallyEnvelopedByTopSoilLayer_ReturnsExpectedSoilProfile2D()
{
// Setup
const string bottomLayerName = "BottomLayer";
const string middleLayerName = "MiddleLayer";
const string topLayerName = "TopLayer";
SoilLayer1D bottomLayer = CreateSoilLayer(-5, bottomLayerName);
SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName);
var profile = new SoilProfile1D();
profile.Layers.Add(bottomLayer);
profile.Layers.Add(middleLayer);
profile.BottomLevel = -10;
SurfaceLine2 surfaceLine = CreateSurfaceLine(new[]
{
new GeometryPoint(0, -2.5),
new GeometryPoint(5, 2.5),
new GeometryPoint(10, -2.5)
});
var soilSurfaceProfile = new SoilSurfaceProfile
{
SoilProfile = profile,
SurfaceLine2 = surfaceLine,
DikeEmbankmentMaterial = new Soil
{
Name = topLayerName
}
};
// Call
SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D();
// Assert
var soilLayer2Ds = soilProfile2D.Surfaces;
Assert.That(soilLayer2Ds, Has.Count.EqualTo(3));
SoilLayer2D topSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, topLayerName));
AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, topSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(2.5, 0), new Point2D(5, 2.5)),
new GeometryCurve(new Point2D(5, 2.5), new Point2D(7.5, 0)),
new GeometryCurve(new Point2D(7.5, 0), new Point2D(5, 0)),
new GeometryCurve(new Point2D(5, 0), new Point2D(2.5, 0))
}, topSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
SoilLayer2D middleSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName));
AssertSoilLayerProperties(middleLayer, middleSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -2.5), new Point2D(2.5, 0)),
new GeometryCurve(new Point2D(2.5, 0), new Point2D(5, 0)),
new GeometryCurve(new Point2D(5, 0), new Point2D(7.5, 0)),
new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, -2.5)),
new GeometryCurve(new Point2D(10, -2.5), new Point2D(10, -5)),
new GeometryCurve(new Point2D(10, -5), new Point2D(7.5, -5)),
new GeometryCurve(new Point2D(7.5, -5), new Point2D(5, -5)),
new GeometryCurve(new Point2D(5, -5), new Point2D(2.5, -5)),
new GeometryCurve(new Point2D(2.5, -5), new Point2D(0, -5)),
new GeometryCurve(new Point2D(0, -5), new Point2D(0, -2.5))
}, middleSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
SoilLayer2D bottomSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName));
AssertSoilLayerProperties(bottomLayer, bottomSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -5), new Point2D(2.5, -5)),
new GeometryCurve(new Point2D(2.5, -5), new Point2D(5, -5)),
new GeometryCurve(new Point2D(5, -5), new Point2D(7.5, -5)),
new GeometryCurve(new Point2D(7.5, -5), new Point2D(10, -5)),
new GeometryCurve(new Point2D(10, -5), new Point2D(10, -10)),
new GeometryCurve(new Point2D(10, -10), new Point2D(7.5, -10)),
new GeometryCurve(new Point2D(7.5, -10), new Point2D(5, -10)),
new GeometryCurve(new Point2D(5, -10), new Point2D(2.5, -10)),
new GeometryCurve(new Point2D(2.5, -10), new Point2D(0, -10)),
new GeometryCurve(new Point2D(0, -10), new Point2D(0, -5))
}, bottomSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
}
[Test]
public void ConvertToSoilProfile2D_WithSurfaceLineIntersectingSoilLayers_ReturnsExpectedSoilProfile()
{
// Setup
const string bottomLayerName = "BottomLayer";
const string middleLayerName = "MiddleLayer";
const string topLayerName = "TopLayer";
SoilLayer1D bottomLayer = CreateSoilLayer(-1.25, bottomLayerName);
SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName);
var profile = new SoilProfile1D();
profile.Layers.Add(bottomLayer);
profile.Layers.Add(middleLayer);
profile.BottomLevel = -10;
SurfaceLine2 surfaceLine = CreateSurfaceLine(new[]
{
new GeometryPoint(0, 2.5),
new GeometryPoint(5, -2.5),
new GeometryPoint(10, 2.5)
});
var soilSurfaceProfile = new SoilSurfaceProfile
{
SoilProfile = profile,
SurfaceLine2 = surfaceLine,
DikeEmbankmentMaterial = new Soil
{
Name = topLayerName
}
};
// Call
SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D();
// Assert
var soilLayer2Ds = soilProfile2D.Surfaces;
Assert.That(soilLayer2Ds, Has.Count.EqualTo(5));
var topSoilLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, topLayerName)).ToArray();
Assert.That(topSoilLayerSurfaces.Length, Is.EqualTo(2));
foreach (SoilLayer2D surface in topSoilLayerSurfaces)
{
AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, surface);
}
AssertGeometry(new []
{
new GeometryCurve(new Point2D(0, 2.5), new Point2D(2.5, 0)),
new GeometryCurve(new Point2D(2.5, 0), new Point2D(0, 0)),
new GeometryCurve(new Point2D(0, 0), new Point2D(0, 2.5))
}, topSoilLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 2.5)),
new GeometryCurve(new Point2D(10, 2.5), new Point2D(10, 0)),
new GeometryCurve(new Point2D(10, 0), new Point2D(7.5, 0))
}, topSoilLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList);
var middleLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, middleLayerName)).ToArray();
Assert.That(middleLayerSurfaces.Length, Is.EqualTo(2));
foreach (SoilLayer2D surface in middleLayerSurfaces)
{
AssertSoilLayerProperties(middleLayer, surface);
}
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, 0), new Point2D(2.5, 0)),
new GeometryCurve(new Point2D(2.5, 0), new Point2D(3.75, -1.25)),
new GeometryCurve(new Point2D(3.75, -1.25), new Point2D(2.5, -1.25)),
new GeometryCurve(new Point2D(2.5, -1.25), new Point2D(0, -1.25)),
new GeometryCurve(new Point2D(0, -1.25), new Point2D(0, 0))
}, middleLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 0)),
new GeometryCurve(new Point2D(10, 0), new Point2D(10, -1.25)),
new GeometryCurve(new Point2D(10, -1.25), new Point2D(7.5, -1.25)),
new GeometryCurve(new Point2D(7.5, -1.25), new Point2D(6.25, -1.25)),
new GeometryCurve(new Point2D(6.25, -1.25), new Point2D(7.5, 0))
}, middleLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList);
SoilLayer2D bottomLayerSurface = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName));
AssertSoilLayerProperties(bottomLayer, bottomLayerSurface);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -1.25), new Point2D(2.5, -1.25)),
new GeometryCurve(new Point2D(2.5, -1.25), new Point2D(3.75, -1.25)),
new GeometryCurve(new Point2D(3.75, -1.25), new Point2D(5, -2.5)),
new GeometryCurve(new Point2D(5, -2.5), new Point2D(6.25, -1.25)),
new GeometryCurve(new Point2D(6.25, -1.25), new Point2D(7.5, -1.25)),
new GeometryCurve(new Point2D(7.5, -1.25), new Point2D(10, -1.25)),
new GeometryCurve(new Point2D(10, -1.25), new Point2D(10, -10)),
new GeometryCurve(new Point2D(10, -10), new Point2D(7.5, -10)),
new GeometryCurve(new Point2D(7.5, -10), new Point2D(6.25, -10)),
new GeometryCurve(new Point2D(6.25, -10), new Point2D(5, -10)),
new GeometryCurve(new Point2D(5, -10), new Point2D(3.75, -10)),
new GeometryCurve(new Point2D(3.75, -10), new Point2D(2.5, -10)),
new GeometryCurve(new Point2D(2.5, -10), new Point2D(0, -10)),
new GeometryCurve(new Point2D(0, -10), new Point2D(0, -1.25))
}, bottomLayerSurface.GeometrySurface.OuterLoop.CurveList);
}
[Test]
public void ConvertToSoilProfile2D_WithSurfaceLineIntersectingSoilLayerAndInflectionAtBottomIntersection_ReturnsExpectedSoilProfile()
{
// Setup
const string bottomLayerName = "BottomLayer";
const string middleLayerName = "MiddleLayer";
const string topLayerName = "TopLayer";
SoilLayer1D bottomLayer = CreateSoilLayer(-2.5, bottomLayerName);
SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName);
var profile = new SoilProfile1D();
profile.Layers.Add(bottomLayer);
profile.Layers.Add(middleLayer);
profile.BottomLevel = -10;
SurfaceLine2 surfaceLine = CreateSurfaceLine(new[]
{
new GeometryPoint(0, 2.5),
new GeometryPoint(5, -2.5),
new GeometryPoint(10, 2.5)
});
var soilSurfaceProfile = new SoilSurfaceProfile
{
SoilProfile = profile,
SurfaceLine2 = surfaceLine,
DikeEmbankmentMaterial = new Soil
{
Name = topLayerName
}
};
// Call
SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D();
// Assert
var soilLayer2Ds = soilProfile2D.Surfaces;
Assert.That(soilLayer2Ds, Has.Count.EqualTo(5));
var topSoilLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, topLayerName)).ToArray();
Assert.That(topSoilLayerSurfaces.Length, Is.EqualTo(2));
foreach (SoilLayer2D surface in topSoilLayerSurfaces)
{
AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, surface);
}
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, 2.5), new Point2D(2.5, 0)),
new GeometryCurve(new Point2D(2.5, 0), new Point2D(0, 0)),
new GeometryCurve(new Point2D(0, 0), new Point2D(0, 2.5))
}, topSoilLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 2.5)),
new GeometryCurve(new Point2D(10, 2.5), new Point2D(10, 0)),
new GeometryCurve(new Point2D(10, 0), new Point2D(7.5, 0))
}, topSoilLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList);
var middleLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, middleLayerName)).ToArray();
Assert.That(middleLayerSurfaces.Length, Is.EqualTo(2));
foreach (SoilLayer2D surface in middleLayerSurfaces)
{
AssertSoilLayerProperties(middleLayer, surface);
}
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, 0), new Point2D(2.5, 0)),
new GeometryCurve(new Point2D(2.5, 0), new Point2D(5, -2.5)),
new GeometryCurve(new Point2D(5, -2.5), new Point2D(2.5, -2.5)),
new GeometryCurve(new Point2D(2.5, -2.5), new Point2D(0, -2.5)),
new GeometryCurve(new Point2D(0, -2.5), new Point2D(0, 0))
}, middleLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 0)),
new GeometryCurve(new Point2D(10, 0), new Point2D(10, -2.5)),
new GeometryCurve(new Point2D(10, -2.5), new Point2D(7.5, -2.5)),
new GeometryCurve(new Point2D(7.5, -2.5), new Point2D(5, -2.5)),
new GeometryCurve(new Point2D(5, -2.5), new Point2D(7.5, 0))
}, middleLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList);
SoilLayer2D bottomLayerSurface = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName));
AssertSoilLayerProperties(bottomLayer, bottomLayerSurface);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -2.5), new Point2D(2.5, -2.5)),
new GeometryCurve(new Point2D(2.5, -2.5), new Point2D(5, -2.5)),
new GeometryCurve(new Point2D(5, -2.5), new Point2D(7.5, -2.5)),
new GeometryCurve(new Point2D(7.5, -2.5), new Point2D(10, -2.5)),
new GeometryCurve(new Point2D(10, -2.5), new Point2D(10, -10)),
new GeometryCurve(new Point2D(10, -10), new Point2D(7.5, -10)),
new GeometryCurve(new Point2D(7.5, -10), new Point2D(5, -10)),
new GeometryCurve(new Point2D(5, -10), new Point2D(2.5, -10)),
new GeometryCurve(new Point2D(2.5, -10), new Point2D(0, -10)),
new GeometryCurve(new Point2D(0, -10), new Point2D(0, -2.5))
}, bottomLayerSurface.GeometrySurface.OuterLoop.CurveList);
}
[Test]
public void ConvertToSoilProfile2D_WithSurfaceLineIntersectingSoilLayerAndHorizontalLineAtBottomIntersection_ReturnsExpectedSoilProfile()
{
// Setup
const string bottomLayerName = "BottomLayer";
const string middleLayerName = "MiddleLayer";
const string topLayerName = "TopLayer";
SoilLayer1D bottomLayer = CreateSoilLayer(-2.5, bottomLayerName);
SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName);
var profile = new SoilProfile1D();
profile.Layers.Add(bottomLayer);
profile.Layers.Add(middleLayer);
profile.BottomLevel = -10;
SurfaceLine2 surfaceLine = CreateSurfaceLine(new[]
{
new GeometryPoint(0, 2.5),
new GeometryPoint(5, -2.5),
new GeometryPoint(10, -2.5),
new GeometryPoint(15, 2.5)
});
var soilSurfaceProfile = new SoilSurfaceProfile
{
SoilProfile = profile,
SurfaceLine2 = surfaceLine,
DikeEmbankmentMaterial = new Soil
{
Name = topLayerName
}
};
// Call
SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D();
// Assert
var soilLayer2Ds = soilProfile2D.Surfaces;
Assert.That(soilLayer2Ds, Has.Count.EqualTo(5));
var topSoilLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, topLayerName)).ToArray();
Assert.That(topSoilLayerSurfaces.Length, Is.EqualTo(2));
foreach (SoilLayer2D surface in topSoilLayerSurfaces)
{
AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, surface);
}
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, 2.5), new Point2D(2.5, 0)),
new GeometryCurve(new Point2D(2.5, 0), new Point2D(0, 0)),
new GeometryCurve(new Point2D(0, 0), new Point2D(0, 2.5))
}, topSoilLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(12.5, 0), new Point2D(15, 2.5)),
new GeometryCurve(new Point2D(15, 2.5), new Point2D(15, 0)),
new GeometryCurve(new Point2D(15, 0), new Point2D(12.5, 0))
}, topSoilLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList);
var middleLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, middleLayerName)).ToArray();
Assert.That(middleLayerSurfaces.Length, Is.EqualTo(2));
foreach (SoilLayer2D surface in middleLayerSurfaces)
{
AssertSoilLayerProperties(middleLayer, surface);
}
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, 0), new Point2D(2.5, 0)),
new GeometryCurve(new Point2D(2.5, 0), new Point2D(5, -2.5)),
new GeometryCurve(new Point2D(5, -2.5), new Point2D(2.5, -2.5)),
new GeometryCurve(new Point2D(2.5, -2.5), new Point2D(0, -2.5)),
new GeometryCurve(new Point2D(0, -2.5), new Point2D(0, 0))
}, middleLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(12.5, 0), new Point2D(15, 0)),
new GeometryCurve(new Point2D(15, 0), new Point2D(15, -2.5)),
new GeometryCurve(new Point2D(15, -2.5), new Point2D(12.5, -2.5)),
new GeometryCurve(new Point2D(12.5, -2.5), new Point2D(10, -2.5)),
new GeometryCurve(new Point2D(10, -2.5), new Point2D(12.5, 0))
}, middleLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList);
SoilLayer2D bottomLayerSurface = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName));
AssertSoilLayerProperties(bottomLayer, bottomLayerSurface);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -2.5), new Point2D(2.5, -2.5)),
new GeometryCurve(new Point2D(2.5, -2.5), new Point2D(5, -2.5)),
new GeometryCurve(new Point2D(5, -2.5), new Point2D(10, -2.5)),
new GeometryCurve(new Point2D(10, -2.5), new Point2D(12.5, -2.5)),
new GeometryCurve(new Point2D(12.5, -2.5), new Point2D(15, -2.5)),
new GeometryCurve(new Point2D(15, -2.5), new Point2D(15, -10)),
new GeometryCurve(new Point2D(15, -10), new Point2D(12.5, -10)),
new GeometryCurve(new Point2D(12.5, -10), new Point2D(10, -10)),
new GeometryCurve(new Point2D(10, -10), new Point2D(5, -10)),
new GeometryCurve(new Point2D(5, -10), new Point2D(2.5, -10)),
new GeometryCurve(new Point2D(2.5, -10), new Point2D(0, -10)),
new GeometryCurve(new Point2D(0, -10), new Point2D(0, -2.5))
}, bottomLayerSurface.GeometrySurface.OuterLoop.CurveList);
}
[Test]
public void ConvertToSoilProfile2D_WithSurfaceLineStartingHorizontallyAtBottomLayer_ReturnsExpectedSoilProfile()
{
// Setup
const string bottomLayerName = "BottomLayer";
const string middleLayerName = "MiddleLayer";
const string topLayerName = "TopLayer";
SoilLayer1D bottomLayer = CreateSoilLayer(-2.5, bottomLayerName);
SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName);
var profile = new SoilProfile1D();
profile.Layers.Add(bottomLayer);
profile.Layers.Add(middleLayer);
profile.BottomLevel = -10;
SurfaceLine2 surfaceLine = CreateSurfaceLine(new[]
{
new GeometryPoint(0, -2.5),
new GeometryPoint(5, -2.5),
new GeometryPoint(10, 2.5),
new GeometryPoint(15, -2.5),
new GeometryPoint(20, -2.5)
});
var soilSurfaceProfile = new SoilSurfaceProfile
{
SoilProfile = profile,
SurfaceLine2 = surfaceLine,
DikeEmbankmentMaterial = new Soil
{
Name = topLayerName
}
};
// Call
SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D();
// Assert
var soilLayer2Ds = soilProfile2D.Surfaces;
SoilLayer2D topSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, topLayerName));
AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, topSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 2.5)),
new GeometryCurve(new Point2D(10, 2.5), new Point2D(12.5, 0)),
new GeometryCurve(new Point2D(12.5, 0), new Point2D(10, 0)),
new GeometryCurve(new Point2D(10, 0), new Point2D(7.5, 0))
}, topSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
SoilLayer2D middleSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName));
AssertSoilLayerProperties(middleLayer, middleSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(5, -2.5), new Point2D(7.5, 0)),
new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 0)),
new GeometryCurve(new Point2D(10, 0), new Point2D(12.5, 0)),
new GeometryCurve(new Point2D(12.5, 0), new Point2D(15, -2.5)),
new GeometryCurve(new Point2D(15, -2.5), new Point2D(12.5, -2.5)),
new GeometryCurve(new Point2D(12.5, -2.5), new Point2D(10, -2.5)),
new GeometryCurve(new Point2D(10, -2.5), new Point2D(7.5, -2.5)),
new GeometryCurve(new Point2D(7.5, -2.5), new Point2D(5, -2.5))
}, middleSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
SoilLayer2D bottomSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName));
AssertSoilLayerProperties(bottomLayer, bottomSoilLayer2D);
AssertGeometry(new[]
{
new GeometryCurve(new Point2D(0, -2.5), new Point2D(5, -2.5)),
new GeometryCurve(new Point2D(5, -2.5), new Point2D(7.5, -2.5)),
new GeometryCurve(new Point2D(7.5, -2.5), new Point2D(10, -2.5)),
new GeometryCurve(new Point2D(10, -2.5), new Point2D(12.5, -2.5)),
new GeometryCurve(new Point2D(12.5, -2.5), new Point2D(15, -2.5)),
new GeometryCurve(new Point2D(15, -2.5), new Point2D(20, -2.5)),
new GeometryCurve(new Point2D(20, -2.5), new Point2D(20, -10)),
new GeometryCurve(new Point2D(20, -10), new Point2D(15, -10)),
new GeometryCurve(new Point2D(15, -10), new Point2D(12.5, -10)),
new GeometryCurve(new Point2D(12.5, -10), new Point2D(10, -10)),
new GeometryCurve(new Point2D(10, -10), new Point2D(7.5, -10)),
new GeometryCurve(new Point2D(7.5, -10), new Point2D(5, -10)),
new GeometryCurve(new Point2D(5, -10), new Point2D(0, -10)),
new GeometryCurve(new Point2D(0, -10), new Point2D(0, -2.5))
}, bottomSoilLayer2D.GeometrySurface.OuterLoop.CurveList);
}
private static void AssertGeometry(IEnumerable expectedCurves, IEnumerable actualCurves)
{
int nrOfExpectedCurves = expectedCurves.Count();
Assert.That(actualCurves.Count(), Is.EqualTo(nrOfExpectedCurves));
var actualCurveString = actualCurves.Select(c => string.Format("Coordinate ({0}, {1}) --> ({2}, {3})", c.HeadPoint.X, c.HeadPoint.Z, c.EndPoint.X, c.EndPoint.Z));
foreach (GeometryCurve expectedCurve in expectedCurves)
{
Assert.That(actualCurves.Any(c => c.LocationEquals(expectedCurve)), Is.True,
$"Expected curve ({expectedCurve.HeadPoint.X}, {expectedCurve.HeadPoint.Z}) --> ({expectedCurve.EndPoint.X}, {expectedCurve.EndPoint.Z}) not found. " +
$"Actual curves {string.Join(", ", actualCurveString)}");
}
}
private static void AssertSoilLayerProperties(SoilLayer1D expectedLayer,
SoilLayer2D actualSoilLayer)
{
Assert.That(actualSoilLayer.IsAquifer, Is.EqualTo(expectedLayer.IsAquifer));
Assert.That(actualSoilLayer.WaterpressureInterpolationModel, Is.EqualTo(expectedLayer.WaterpressureInterpolationModel));
Assert.That(actualSoilLayer.Soil, Is.SameAs(expectedLayer.Soil));
}
private static void AssertDikeEmbankmentSoilLayerProperties(SoilSurfaceProfile expectedProfile,
SoilLayer2D actualSoilLayer)
{
Assert.That(actualSoilLayer.IsAquifer, Is.False);
Assert.That(actualSoilLayer.WaterpressureInterpolationModel, Is.EqualTo(WaterpressureInterpolationModel.Hydrostatic));
Assert.That(actualSoilLayer.Soil, Is.SameAs(expectedProfile.DikeEmbankmentMaterial));
}
private static SoilLayer1D CreateSoilLayer(double topLevel, string soilName)
{
var random = new Random(soilName.GetHashCode());
Array values = Enum.GetValues(typeof(WaterpressureInterpolationModel));
var model = (WaterpressureInterpolationModel)values.GetValue(random.Next(values.Length));
return new SoilLayer1D
{
TopLevel = topLevel,
Soil = new Soil(soilName),
IsAquifer = Convert.ToBoolean(random.Next(0, 2)),
WaterpressureInterpolationModel = model
};
}
private static SurfaceLine2 CreateSurfaceLine(IEnumerable coordinates)
{
var surfaceLine = new SurfaceLine2();
surfaceLine.Geometry.Points.AddRange(coordinates);
surfaceLine.Geometry.SyncCalcPoints();
return surfaceLine;
}
}
}