// Copyright (C) Stichting Deltares 2025. 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 Deltares.DamEngine.Calculators.Uplift;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.General.PlLines;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.TestHelpers.Factories;
using NUnit.Framework;
namespace Deltares.DamEngine.Calculators.Tests.Uplift;
[TestFixture]
public class UpliftLocationDeterminatorTest
{
[SetUp]
public void FixtureSetup() {}
[TearDown]
public void FixtureTearDown() {}
[Test]
public void ThrowsExceptionIfSoilProfileNotAssignedInUpliftLocationDeterminator()
{
SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1();
var upliftLocationDeterminator = new UpliftLocationDeterminator();
upliftLocationDeterminator.SurfaceLine = surfaceLineTutorial1;
upliftLocationDeterminator.PlLines = FactoryForPlLines.CreatePlLinesForUpliftLocationDeterminatorTests();
Assert.That(() => upliftLocationDeterminator.GetLocationAndResult(1.0), Throws.InstanceOf());
}
[Test]
public void ThrowsExceptionIfPlLinesNotAssignedInUpliftLocationDeterminator()
{
SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1();
var upliftLocationDeterminator = new UpliftLocationDeterminator();
upliftLocationDeterminator.SurfaceLine = surfaceLineTutorial1;
upliftLocationDeterminator.SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile();
Assert.That(() => upliftLocationDeterminator.GetLocationAndResult(1.0), Throws.InstanceOf());
}
[Test]
public void ThrowsExceptionIfSurfaceLineNotAssignedInUpliftLocationDeterminator()
{
var upliftLocationDeterminator = new UpliftLocationDeterminator();
upliftLocationDeterminator.SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile();
upliftLocationDeterminator.PlLines = FactoryForPlLines.CreatePlLinesForUpliftLocationDeterminatorTests();
Assert.That(() => upliftLocationDeterminator.GetLocationAndResult(1.0), Throws.InstanceOf());
}
[Test]
public void CheckIfUpliftIsDetectedForBothSandlayers()
{
SurfaceLine2 surfaceLineForPipingBligh = FactoryForSurfaceLines.CreateSurfaceLineForPipingBligh();
var upliftLocationDeterminator = new UpliftLocationDeterminator();
upliftLocationDeterminator.SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfileForPipingBligh();
upliftLocationDeterminator.PlLines = FactoryForPlLines.CreatePlLinesForUpliftLocationDeterminatorTests();
upliftLocationDeterminator.SurfaceLine = surfaceLineForPipingBligh;
UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationAndResult(1.0);
Assert.That(upliftLocationAndResult.LocationEquals(upliftLocationDeterminator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder)), Is.True);
}
[Test]
public void GetLowestUpliftFactorCoordinateFromSimpleSurfaceLineAndOneSandLayerProfile()
{
const double cTolerance = 0.000001;
const double cExpectedXCoordinate = 59.5;
const double cExpectedZCoordinate = -2.0;
const double cExpectedUpliftFactor = 0.675781015; // Value taken from calculation itself
// Set required upliftcalculator variables
const double cRiverlevel = 4;
SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineTutorial1();
SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out SoilList soilList);
PlLines plLines = CreatePlLines(surfaceLine, soilProfile, soilList, cRiverlevel, false);
var upliftLocationDeterminator = new UpliftLocationDeterminator
{
SurfaceLine = surfaceLine,
SoilProfile = soilProfile,
PlLines = plLines
};
UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationWithLowestUpliftFactor();
Assert.That(upliftLocationAndResult.X, Is.EqualTo(cExpectedXCoordinate).Within(cTolerance));
Assert.That(upliftLocationAndResult.Z, Is.EqualTo(cExpectedZCoordinate).Within(cTolerance));
Assert.That(upliftLocationAndResult.UpliftFactor.Value, Is.EqualTo(cExpectedUpliftFactor).Within(cTolerance));
}
[Test]
public void GetLocationInPolderNearestDikeWithUpliftFactorLowerThanOneFromSimpleSurfaceLineAndOneSandLayerProfile()
{
const double cTolerance = 0.000001;
const double cExpectedUpliftFactor = 0.0666253589441213; // this value is copied from the debugger
// Set required upliftcalculator variables
const double cRiverlevel = 4;
SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineTutorial1();
SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandProfileForPipingBligh(out SoilList soilList);
PlLines plLines = CreatePlLines(surfaceLine, soilProfile, soilList, cRiverlevel, false);
var upliftLocationDeterminator = new UpliftLocationDeterminator
{
SurfaceLine = surfaceLine,
SoilProfile = soilProfile,
PlLines = plLines
};
UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationInPolderNearestDikeWithUpliftFactorLowerThanRequired(1.0);
Assert.That(upliftLocationAndResult.LocationEquals(upliftLocationDeterminator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder)), Is.True);
Assert.That(upliftLocationAndResult.UpliftFactor.Value, Is.EqualTo(cExpectedUpliftFactor).Within(cTolerance));
}
///
/// Same as above test, but now the oven dry unit weight has to be used
///
[Test]
public void GetLocationInPolderNearestDikeWithUpliftFactorLowerThanOneFromSimpleSurfaceLineAndOneSandLayerProfileAndDryOption()
{
const double cTolerance = 0.000001;
const double cExpectedUpliftFactor = 0.0666253589441213; // this value is copied from the debugger
// Set required upliftcalculator variables
const double cRiverlevel = 4;
SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineTutorial1();
SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandProfileForPipingBligh(out SoilList soilList);
PlLines plLines = CreatePlLines(surfaceLine, soilProfile, soilList, cRiverlevel, false);
var upliftLocationDeterminator = new UpliftLocationDeterminator
{
SurfaceLine = surfaceLine,
SoilProfile = soilProfile,
PlLines = plLines
};
UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationInPolderNearestDikeWithUpliftFactorLowerThanRequired(1.0);
Assert.Multiple(() =>
{
Assert.That(upliftLocationAndResult.LocationEquals(upliftLocationDeterminator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder)), Is.True);
Assert.That(upliftLocationAndResult.UpliftFactor.Value, Is.EqualTo(cExpectedUpliftFactor).Within(cTolerance));
});
}
private static PlLines CreatePlLines(SurfaceLine2 surfaceLine, SoilProfile1D soilProfile, SoilList soilList, double riverLevel, bool isUseOvenDryUnitWeight)
{
var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator
{
SoilProfile = soilProfile,
SurfaceLine = surfaceLine,
SoilList = soilList,
DikeEmbankmentMaterial = soilList.Soils[0],
WaterLevelRiverHigh = riverLevel,
WaterLevelPolder = -0.5,
ModelParametersForPlLines =
{
DampingFactorPl3 = 0.3,
DampingFactorPl4 = 0.4,
PenetrationLength = 1.5
},
IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = false // for piping this must be set to false
};
var location = new Location();
return plLineCreator.CreateAllPlLines(location, out _);
}
}