// Copyright (C) Stichting Deltares 2024. 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.Collections.Generic;
using System.Data;
using System.IO;
using Deltares.DamEngine.Calculators.KernelWrappers.Common;
using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces;
using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards;
using Deltares.DamEngine.Calculators.Tests.KernelWrappers.TestHelpers;
using Deltares.DamEngine.Data.Design;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.General.Results;
using Deltares.DamEngine.Data.Geometry;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard.Calculation;
using Deltares.DamEngine.Data.Standard.Logging;
using Deltares.DamEngine.Interface;
using Deltares.DamEngine.Io.XmlOutput;
using Deltares.DamEngine.TestHelpers;
using Deltares.DamEngine.TestHelpers.Factories;
using NUnit.Framework;
using DesignResult = Deltares.DamEngine.Data.General.Results.DesignResult;
using UpliftSituation = Deltares.DamEngine.Data.General.UpliftSituation;
namespace Deltares.DamEngine.Calculators.Tests.KernelWrappers.MacroStabilityInwards;
[TestFixture]
public class MacroStabilityInwardsKernelWrapperTests
{
private const string TestFolder = @"..\..\..\Deltares.DamEngine.IntegrationTests\TestFiles";
private readonly string inputXmlForDamEngine = Path.Combine(TestFolder, "StabilityDesign1Dbased.xml");
[Test]
public void TestPrepare()
{
var kernelWrapper = new MacroStabilityInwardsKernelWrapper
{
FailureMechanismParametersMStab = new FailureMechanismParametersMStab
{
MStabParameters =
{
Model = MStabModelType.UpliftVan
}
}
};
DamKernelInput kernelInput = CreateDamKernelInputForTest();
// Situation 1: no uplift. Expected PrepareResult.NotRelevant
kernelInput.Location.ModelFactors.UpliftCriterionStability = 0.8;
PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out _, out IKernelDataOutput kernelDataOutput);
Assert.AreEqual(PrepareResult.NotRelevant, prepareResult);
var damMacroStabilityOutput = (MacroStabilityOutput) kernelDataOutput;
Assert.AreEqual(CalculationResult.NoRun, damMacroStabilityOutput.CalculationResult);
Assert.AreEqual(false, damMacroStabilityOutput.UpliftSituation.IsUplift);
// Situation 2: there is uplift and prepare succeeds. Expected PrepareResult.Successful
kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4;
prepareResult = kernelWrapper.Prepare(kernelInput, 0, out _, out kernelDataOutput);
Assert.AreEqual(PrepareResult.Successful, prepareResult);
damMacroStabilityOutput = (MacroStabilityOutput) kernelDataOutput;
Assert.AreEqual(CalculationResult.NoRun, damMacroStabilityOutput.CalculationResult);
Assert.AreEqual(true, damMacroStabilityOutput.UpliftSituation.IsUplift);
// Situation 3: prepare fails. Expected PrepareResult.Failed
kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.2;
kernelInput.Location.SurfaceLine.CharacteristicPoints.Clear();
prepareResult = kernelWrapper.Prepare(kernelInput, 0, out _, out kernelDataOutput);
Assert.AreEqual(PrepareResult.Failed, prepareResult);
damMacroStabilityOutput = (MacroStabilityOutput) kernelDataOutput;
Assert.AreEqual(CalculationResult.NoRun, damMacroStabilityOutput.CalculationResult);
}
[Test]
public void TestValidate()
{
var kernelWrapper = new MacroStabilityInwardsKernelWrapper
{
FailureMechanismParametersMStab = new FailureMechanismParametersMStab
{
MStabParameters =
{
Model = MStabModelType.UpliftVan
}
}
};
// Validate without setting values. Expected error messages.
var macroStabilityInput = new MacroStabilityKernelDataInput();
var macroStabilityOutput = new MacroStabilityOutput
{
CalculationResult = CalculationResult.NoRun
};
int errorCount = kernelWrapper.Validate(macroStabilityInput, macroStabilityOutput, out List messages);
Assert.IsTrue(errorCount > 0);
Assert.AreEqual(CalculationResult.InvalidInputData, macroStabilityOutput.CalculationResult);
// Validate the input when valid input is provided. Expected no messages.
DamKernelInput kernelInput = CreateDamKernelInputForTest();
kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4;
PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput);
Assert.IsTrue(prepareResult == PrepareResult.Successful);
messages.Clear();
errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out messages);
Assert.IsTrue(errorCount == 0);
Assert.AreEqual(CalculationResult.NoRun, ((MacroStabilityOutput) kernelDataOutput).CalculationResult);
}
[Test]
[TestCase(MStabModelType.Bishop)]
[TestCase(MStabModelType.UpliftVan)]
[TestCase(MStabModelType.BishopUpliftVan)]
public void TestPostProcess(MStabModelType modelType)
{
var kernelWrapper = new MacroStabilityInwardsKernelWrapper
{
FailureMechanismParametersMStab = new FailureMechanismParametersMStab
{
MStabParameters =
{
Model = modelType
}
}
};
DamKernelInput kernelInput = CreateDamKernelInputForTest();
var macroStabilityOutput = new MacroStabilityOutput
{
CalculationResult = CalculationResult.Succeeded,
UpliftSituation = new UpliftSituation
{
IsUplift = true
},
StabilityOutputItems = new List
{
new MacroStabilityOutputItem
{
StabilityModelType = modelType != MStabModelType.BishopUpliftVan ? modelType : MStabModelType.Bishop,
CalculationResult = CalculationResult.Succeeded,
SafetyFactor = 2.34,
CalculationPath = TestFolder + "@\testpath",
ProjectName = Path.GetFileNameWithoutExtension(inputXmlForDamEngine),
ActiveCenterPoint = new Point2D(10, 10),
ActiveCenterPointRadius = 8,
PassiveCenterPoint = new Point2D(22, 11),
PassiveCenterPointRadius = 7
}
}
};
if (modelType == MStabModelType.BishopUpliftVan)
{
var macroStabilityOutputItem = new MacroStabilityOutputItem
{
StabilityModelType = MStabModelType.UpliftVan,
CalculationResult = CalculationResult.Succeeded,
SafetyFactor = 2.01,
ActiveCenterPoint = new Point2D(10, 10),
ActiveCenterPointRadius = 8,
PassiveCenterPoint = new Point2D(22, 11),
PassiveCenterPointRadius = 7
};
macroStabilityOutput.StabilityOutputItems.Add(macroStabilityOutputItem);
}
var designScenario = new DesignScenario
{
LocationName = kernelInput.Location.Name
};
var resultSlice = new StabilityResultSlice
{
TopLeftPoint = new Point2D(9, 3),
TopRightPoint = new Point2D(9.2, 3.01),
BottomLeftPoint = new Point2D(9, -3),
BottomRightPoint = new Point2D(9.2, -3.1),
Name = "slice1",
Width = 0.2,
ArcLength = 0.22,
TopAngle = 0,
BottomAngle = 12.2,
CohesionInput = 14,
Cohesion = 14.5,
CohesionCalculated = 15.5,
FrictionAngleInput = 30,
FrictionAngle = 30.5,
YieldStress = 22,
OCR = 23,
POP = 24,
DegreeOfConsolidationPorePressure = 25,
PorePressureDueToDegreeOfConsolidationLoad = 26,
DilatancyInput = 27,
Dilatancy = 28,
ExternalLoad = 29,
HydrostaticPorePressure = 30,
LeftForce = 31,
LeftForceAngle = 32,
LeftForceY = 33,
RightForce = 34,
RightForceAngle = 35,
RightForceY = 36,
LoadStress = 37,
NormalStress = 38,
PorePressure = 39,
HorizontalPorePressure = 40,
VerticalPorePressure = 41,
PiezometricPorePressure = 42,
EffectiveStress = 43,
ExcessPorePressure = 44,
ShearStress = 45,
SoilStress = 46,
TotalPorePressure = 47,
TotalStress = 48,
Weight = 49,
Su = 50,
ShearStrengthModel = ShearStrengthModel.CPhi,
HorizontalSoilQuakeStress = 51,
StrengthIncreaseExponent = 52,
UpliftFactor = 53,
VerticalSoilQuakeStress = 54,
WaterQuakeStress = 55,
UpliftReductionFactor = 56,
RatioCuPc = 57,
ResultantForce = 58,
ResultantMoment = 59,
ResultantAngle = 60
};
macroStabilityOutput.StabilityOutputItems[0].ResultSlices = new List
{
resultSlice
};
if (modelType == MStabModelType.BishopUpliftVan)
{
macroStabilityOutput.StabilityOutputItems[1].ResultSlices = new List
{
resultSlice
};
}
kernelWrapper.PostProcess(kernelInput, macroStabilityOutput, designScenario, "", out List results);
switch (modelType)
{
case MStabModelType.Bishop:
case MStabModelType.UpliftVan:
Assert.AreEqual(1, results.Count);
break;
case MStabModelType.BishopUpliftVan:
Assert.AreEqual(3, results.Count);
break;
}
var expectedNumberOfIterations = new List();
var expectedStabilityModelType = new List();
var expectedSafetyFactor = new List();
switch (modelType)
{
case MStabModelType.Bishop:
expectedNumberOfIterations = new List
{
0
};
expectedStabilityModelType = new List
{
MStabModelType.Bishop
};
expectedSafetyFactor = new List
{
2.34
};
break;
case MStabModelType.UpliftVan:
expectedNumberOfIterations = new List
{
0
};
expectedStabilityModelType = new List
{
MStabModelType.UpliftVan
};
expectedSafetyFactor = new List
{
2.34
};
break;
case MStabModelType.BishopUpliftVan:
expectedNumberOfIterations = new List
{
0,
0,
null
};
expectedStabilityModelType = new List
{
MStabModelType.Bishop,
MStabModelType.UpliftVan,
MStabModelType.BishopUpliftVan
};
expectedSafetyFactor = new List
{
2.34,
2.01,
2.01
};
break;
}
for (var index = 0; index < results.Count; index++)
{
DesignResult result = results[index];
Assert.AreEqual(CalculationResult.Succeeded, result.CalculationResult);
Assert.AreEqual(true, ((UpliftSituation) result.StabilityDesignResults.UpliftSituation).IsUplift);
if (index == 0)
{
Assert.AreEqual(Path.GetFileNameWithoutExtension(inputXmlForDamEngine), result.BaseFileName);
Assert.AreEqual(TestFolder + "@\testpath", result.CalculationSubDir);
}
Assert.AreEqual(expectedNumberOfIterations[index], result.StabilityDesignResults.NumberOfIterations);
Assert.AreEqual(expectedSafetyFactor[index], result.StabilityDesignResults.SafetyFactor);
Assert.AreEqual(kernelInput.Location.SurfaceLine, result.StabilityDesignResults.RedesignedSurfaceLine);
Assert.AreEqual(kernelInput.SubSoilScenario.ToString(), result.ProfileName);
Assert.AreEqual(expectedStabilityModelType[index], result.StabilityDesignResults.StabilityModelType);
Assert.AreEqual(10, result.StabilityDesignResults.ActiveCenterPoint.X);
Assert.AreEqual(10, result.StabilityDesignResults.ActiveCenterPoint.Z);
Assert.AreEqual(8, result.StabilityDesignResults.ActiveCenterPointRadius);
if (result.StabilityDesignResults.StabilityModelType != MStabModelType.Bishop)
{
Assert.AreEqual(22, result.StabilityDesignResults.PassiveCenterPoint.X);
Assert.AreEqual(11, result.StabilityDesignResults.PassiveCenterPoint.Z);
Assert.AreEqual(7, result.StabilityDesignResults.PassiveCenterPointRadius);
}
Assert.AreEqual(9, result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.X);
Assert.AreEqual(3, result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.Z);
Assert.AreEqual(9.2, result.StabilityDesignResults.ResultSlices[0].TopRightPoint.X);
Assert.AreEqual(3.01, result.StabilityDesignResults.ResultSlices[0].TopRightPoint.Z);
Assert.AreEqual(9, result.StabilityDesignResults.ResultSlices[0].BottomLeftPoint.X);
Assert.AreEqual(-3, result.StabilityDesignResults.ResultSlices[0].BottomLeftPoint.Z);
Assert.AreEqual(9.2, result.StabilityDesignResults.ResultSlices[0].BottomRightPoint.X);
Assert.AreEqual(-3.1, result.StabilityDesignResults.ResultSlices[0].BottomRightPoint.Z);
Assert.AreEqual("slice1", result.StabilityDesignResults.ResultSlices[0].Name);
Assert.AreEqual(0.2, result.StabilityDesignResults.ResultSlices[0].Width);
Assert.AreEqual(0.22, result.StabilityDesignResults.ResultSlices[0].ArcLength);
Assert.AreEqual(0, result.StabilityDesignResults.ResultSlices[0].TopAngle);
Assert.AreEqual(12.2, result.StabilityDesignResults.ResultSlices[0].BottomAngle);
Assert.AreEqual(14, result.StabilityDesignResults.ResultSlices[0].CohesionInput);
Assert.AreEqual(14.5, result.StabilityDesignResults.ResultSlices[0].Cohesion);
Assert.AreEqual(15.5, result.StabilityDesignResults.ResultSlices[0].CohesionCalculated);
Assert.AreEqual(30, result.StabilityDesignResults.ResultSlices[0].FrictionAngleInput);
Assert.AreEqual(30.5, result.StabilityDesignResults.ResultSlices[0].FrictionAngle);
Assert.AreEqual(22, result.StabilityDesignResults.ResultSlices[0].YieldStress);
Assert.AreEqual(23, result.StabilityDesignResults.ResultSlices[0].OCR);
Assert.AreEqual(24, result.StabilityDesignResults.ResultSlices[0].POP);
Assert.AreEqual(25, result.StabilityDesignResults.ResultSlices[0].DegreeOfConsolidationPorePressure);
Assert.AreEqual(26, result.StabilityDesignResults.ResultSlices[0].PorePressureDueToDegreeOfConsolidationLoad);
Assert.AreEqual(27, result.StabilityDesignResults.ResultSlices[0].DilatancyInput);
Assert.AreEqual(28, result.StabilityDesignResults.ResultSlices[0].Dilatancy);
Assert.AreEqual(29, result.StabilityDesignResults.ResultSlices[0].ExternalLoad);
Assert.AreEqual(30, result.StabilityDesignResults.ResultSlices[0].HydrostaticPorePressure);
Assert.AreEqual(31, result.StabilityDesignResults.ResultSlices[0].LeftForce);
Assert.AreEqual(32, result.StabilityDesignResults.ResultSlices[0].LeftForceAngle);
Assert.AreEqual(33, result.StabilityDesignResults.ResultSlices[0].LeftForceY);
Assert.AreEqual(34, result.StabilityDesignResults.ResultSlices[0].RightForce);
Assert.AreEqual(35, result.StabilityDesignResults.ResultSlices[0].RightForceAngle);
Assert.AreEqual(36, result.StabilityDesignResults.ResultSlices[0].RightForceY);
Assert.AreEqual(37, result.StabilityDesignResults.ResultSlices[0].LoadStress);
Assert.AreEqual(38, result.StabilityDesignResults.ResultSlices[0].NormalStress);
Assert.AreEqual(39, result.StabilityDesignResults.ResultSlices[0].PorePressure);
Assert.AreEqual(40, result.StabilityDesignResults.ResultSlices[0].HorizontalPorePressure);
Assert.AreEqual(41, result.StabilityDesignResults.ResultSlices[0].VerticalPorePressure);
Assert.AreEqual(42, result.StabilityDesignResults.ResultSlices[0].PiezometricPorePressure);
Assert.AreEqual(43, result.StabilityDesignResults.ResultSlices[0].EffectiveStress);
Assert.AreEqual(44, result.StabilityDesignResults.ResultSlices[0].ExcessPorePressure);
Assert.AreEqual(45, result.StabilityDesignResults.ResultSlices[0].ShearStress);
Assert.AreEqual(46, result.StabilityDesignResults.ResultSlices[0].SoilStress);
Assert.AreEqual(47, result.StabilityDesignResults.ResultSlices[0].TotalPorePressure);
Assert.AreEqual(48, result.StabilityDesignResults.ResultSlices[0].TotalStress);
Assert.AreEqual(49, result.StabilityDesignResults.ResultSlices[0].Weight);
Assert.AreEqual(50, result.StabilityDesignResults.ResultSlices[0].Su);
Assert.AreEqual(51, result.StabilityDesignResults.ResultSlices[0].HorizontalSoilQuakeStress);
Assert.AreEqual(52, result.StabilityDesignResults.ResultSlices[0].StrengthIncreaseExponent);
Assert.AreEqual(53, result.StabilityDesignResults.ResultSlices[0].UpliftFactor);
Assert.AreEqual(54, result.StabilityDesignResults.ResultSlices[0].VerticalSoilQuakeStress);
Assert.AreEqual(55, result.StabilityDesignResults.ResultSlices[0].WaterQuakeStress);
Assert.AreEqual(56, result.StabilityDesignResults.ResultSlices[0].UpliftReductionFactor);
Assert.AreEqual(57, result.StabilityDesignResults.ResultSlices[0].RatioCuPc);
Assert.AreEqual(58, result.StabilityDesignResults.ResultSlices[0].ResultantForce);
Assert.AreEqual(59, result.StabilityDesignResults.ResultSlices[0].ResultantMoment);
Assert.AreEqual(60, result.StabilityDesignResults.ResultSlices[0].ResultantAngle);
Assert.AreEqual(ShearStrengthModel.CPhi, result.StabilityDesignResults.ResultSlices[0].ShearStrengthModel);
}
}
[Test]
public void TestFullCalculationFails()
{
var kernelWrapper = new MacroStabilityInwardsKernelWrapper
{
FailureMechanismParametersMStab = new FailureMechanismParametersMStab
{
MStabParameters =
{
Model = MStabModelType.UpliftVan
}
}
};
IKernelDataInput kernelDataInput = new MacroStabilityKernelDataInput();
IKernelDataOutput kernelDataOutput = new MacroStabilityOutput();
// Run the dll
kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out List messages);
var macroStabilityOutput = (MacroStabilityOutput) kernelDataOutput;
Assert.IsTrue(messages.Count > 0);
// as there is no data at all, expect unexpected error
Assert.AreEqual(CalculationResult.UnexpectedError, macroStabilityOutput.CalculationResult);
}
[Test]
public void TestFullCalculationSucceedsWithWarningsWithBadTangentLines()
{
var kernelWrapper = new MacroStabilityInwardsKernelWrapper
{
FailureMechanismParametersMStab = new FailureMechanismParametersMStab
{
MStabParameters =
{
Model = MStabModelType.UpliftVan
}
}
};
// Prepare the wrapper. Result is input for the calculation dll
DamKernelInput kernelInput = CreateDamKernelInputForTest();
kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4;
SlipCircleDefinition sd = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab
.MStabParameters.SlipCircleDefinition;
sd.UpliftVanTangentLinesDefinition = TangentLinesDefinition.Specified;
PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput);
Assert.AreEqual(PrepareResult.Successful, prepareResult);
// Validate the input
int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out List messages);
Assert.IsTrue(errorCount == 0);
// Run the dl; the tangent line position is defined in such a way that this calculation will result in
// several failed attempted slip planes so there should be warnings.
kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out messages);
var macroStabilityOutput = (MacroStabilityOutput) kernelDataOutput;
Assert.AreEqual(51, messages.Count);
Assert.AreEqual(CalculationResult.Succeeded, macroStabilityOutput.CalculationResult);
Assert.IsTrue(messages[0].Message.Contains("A slice is beyond the geometry at x"));
}
[Test]
public void TestFullCalculationSucceeds()
{
const double diff = 0.0001;
var kernelWrapper = new MacroStabilityInwardsKernelWrapper
{
FailureMechanismParametersMStab = new FailureMechanismParametersMStab
{
MStabParameters =
{
Model = MStabModelType.UpliftVan
}
}
};
// Prepare the wrapper. Result is input for the calculation dll
DamKernelInput kernelInput = CreateDamKernelInputForTest();
// To ensure uplift occurs, set criterion to 1.4
kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4;
PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput);
Assert.AreEqual(PrepareResult.Successful, prepareResult);
// Validate the input
int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out List messages);
Assert.IsTrue(errorCount == 0);
// Run the dll
kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out messages);
var macroStabilityOutput = (MacroStabilityOutput) kernelDataOutput;
Assert.AreEqual(2, messages.Count);
Assert.AreEqual(CalculationResult.Succeeded, macroStabilityOutput.CalculationResult);
Assert.AreEqual(1, macroStabilityOutput.StabilityOutputItems.Count);
Assert.AreEqual(1.5211, macroStabilityOutput.StabilityOutputItems[0].SafetyFactor, diff); // ToDo replace by actual value when calculation is done and output is parsed
// Fill the design results
var designScenario = new DesignScenario
{
LocationName = kernelInput.Location.Name
};
kernelWrapper.PostProcess(kernelInput, macroStabilityOutput, designScenario, "", out List results);
Assert.IsTrue(results.Count > 0);
foreach (DesignResult result in results)
{
Assert.AreEqual("Loc(TestLocation)_Sce(1)_Pro(DefaultNameSoilProfile1D)", result.BaseFileName);
Assert.AreEqual("..\\Test\\Stability\\UpliftVan", result.CalculationSubDir);
Assert.AreEqual(CalculationResult.Succeeded, result.CalculationResult);
Assert.That(result.StabilityDesignResults.SafetyFactor, Is.EqualTo(1.5211).Within(diff));
Assert.AreEqual(50.5, result.StabilityDesignResults.ActiveCenterPoint.X, diff);
Assert.AreEqual(12, result.StabilityDesignResults.ActiveCenterPoint.Z, diff);
Assert.AreEqual(22, result.StabilityDesignResults.ActiveCenterPointRadius, diff);
Assert.AreEqual(50.5, result.StabilityDesignResults.PassiveCenterPoint.X);
Assert.AreEqual(2.2, result.StabilityDesignResults.PassiveCenterPoint.Z);
Assert.AreEqual(12.2, result.StabilityDesignResults.PassiveCenterPointRadius);
Assert.AreEqual(40, result.StabilityDesignResults.ResultSlices.Count);
Assert.AreEqual(ShearStrengthModel.CPhi, result.StabilityDesignResults.ResultSlices[0].ShearStrengthModel);
Assert.AreEqual(15.8180658, result.StabilityDesignResults.ResultSlices[0].EffectiveStress, diff);
Assert.AreEqual(31, result.StabilityDesignResults.ResultSlices[0].FrictionAngle, diff);
Assert.AreEqual(double.NaN, result.StabilityDesignResults.ResultSlices[0].OCR, diff);
Assert.AreEqual(8.8710528, result.StabilityDesignResults.ResultSlices[0].NormalStress, diff);
Assert.AreEqual(29.9769477, result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.X, diff);
Assert.AreEqual(4.0750819, result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.Z, diff);
Assert.AreEqual(0.6946544, result.StabilityDesignResults.ResultSlices[0].Width, diff);
Assert.AreEqual(10.9880897, result.StabilityDesignResults.ResultSlices[0].Weight, diff);
var index = 21;
Assert.AreEqual(ShearStrengthModel.CPhi, result.StabilityDesignResults.ResultSlices[index].ShearStrengthModel);
Assert.AreEqual(116.6794325, result.StabilityDesignResults.ResultSlices[index].EffectiveStress, diff);
Assert.AreEqual(10, result.StabilityDesignResults.ResultSlices[index].FrictionAngle, diff);
Assert.AreEqual(double.NaN, result.StabilityDesignResults.ResultSlices[index].OCR, diff);
Assert.AreEqual(114.2973685, result.StabilityDesignResults.ResultSlices[index].NormalStress, diff);
Assert.AreEqual(46.8636363, result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.X, diff);
Assert.AreEqual(1.8181818, result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.Z, diff);
Assert.AreEqual(0.9090909, result.StabilityDesignResults.ResultSlices[index].Width, diff);
Assert.AreEqual(193.1479678, result.StabilityDesignResults.ResultSlices[index].Weight, diff);
index = result.StabilityDesignResults.ResultSlices.Count - 1;
Assert.AreEqual(ShearStrengthModel.CPhi, result.StabilityDesignResults.ResultSlices[index].ShearStrengthModel);
Assert.AreEqual(5.5185653, result.StabilityDesignResults.ResultSlices[index].EffectiveStress, diff);
Assert.AreEqual(31, result.StabilityDesignResults.ResultSlices[index].FrictionAngle, diff);
Assert.AreEqual(double.NaN, result.StabilityDesignResults.ResultSlices[index].OCR, diff);
Assert.AreEqual(7.2892231, result.StabilityDesignResults.ResultSlices[index].NormalStress, diff);
Assert.AreEqual(61.5363037, result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.X, diff);
Assert.AreEqual(-1.9273925, result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.Z, diff);
Assert.AreEqual(0.9636962, result.StabilityDesignResults.ResultSlices[index].Width, diff);
Assert.AreEqual(10.3883614, result.StabilityDesignResults.ResultSlices[index].Weight, diff);
}
}
[Test]
public void TestFullCalculationSucceedsWithBeeSwarmAsSearchMethod()
{
const double diff = 0.0001;
var kernelWrapper = new MacroStabilityInwardsKernelWrapper
{
FailureMechanismParametersMStab = new FailureMechanismParametersMStab
{
MStabParameters =
{
Model = MStabModelType.UpliftVan,
SearchMethod = MStabSearchMethod.BeeSwarm
}
}
};
// Prepare the wrapper. Result is input for the calculation dll
DamKernelInput kernelInput = CreateDamKernelInputForTest();
kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters
.SearchMethod = MStabSearchMethod.BeeSwarm;
// To ensure uplift occurs, set criterion to 1.4
kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4;
PrepareResult prepareResult =
kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput);
Assert.AreEqual(PrepareResult.Successful, prepareResult);
// Validate the input
int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out List messages);
Assert.AreEqual(0, errorCount);
// Run the dll
kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out messages);
var macroStabilityOutput = (MacroStabilityOutput) kernelDataOutput;
Assert.AreEqual(3, messages.Count);
Assert.AreEqual(CalculationResult.Succeeded, macroStabilityOutput.CalculationResult);
Assert.AreEqual(1, macroStabilityOutput.StabilityOutputItems.Count);
// SafetyFactor as obtained when running the skx file with this input in the stability kernel directly = 1.9882432331086863
Assert.AreEqual(1.99423, macroStabilityOutput.StabilityOutputItems[0].SafetyFactor, diff);
// Fill the design results
var designScenario = new DesignScenario
{
LocationName = kernelInput.Location.Name
};
kernelWrapper.PostProcess(kernelInput, macroStabilityOutput, designScenario, "", out List results);
Assert.IsTrue(results.Count > 0);
}
[Test]
public void CalculationUpliftBasedOnDamEngineXmlWorks()
{
const string calcDir = "TestStabInwardsBishop";
if (Directory.Exists(calcDir))
{
Directory.Delete(calcDir, true); // delete previous results
}
Directory.CreateDirectory(calcDir);
string inputString = File.ReadAllText(inputXmlForDamEngine);
inputString = XmlAdapter.ChangeValueInXml(inputString, "ProjectPath", ""); // Current directory will be used
inputString = XmlAdapter.ChangeValueInXml(inputString, "CalculationMap", calcDir); // Current directory will be used
var engineInterface = new EngineInterface(inputString);
Assert.IsNotNull(engineInterface.DamProjectData);
engineInterface.DamProjectData.DamProjectCalculationSpecification.CurrentSpecification.StabilityModelType =
MStabModelType.UpliftVan;
Output output = GeneralHelper.RunAfterInputValidation(engineInterface);
Assert.AreEqual(1.638, output.Results.CalculationResults[0].StabilityDesignResults.SafetyFactor, 0.001);
}
[Test]
[SetUICulture("nl-NL")]
public void TestLanguageNLThrowsExceptionWhenInputIsNull()
{
var kernelWrapper = new MacroStabilityInwardsKernelWrapper();
Assert.That(() => kernelWrapper.Execute(null, null, out _), Throws.InstanceOf().With.Message.EqualTo("Geen invoer object gedefinieerd voor Macrostabiliteit"));
}
[Test]
[SetUICulture("en-US")]
public void TestLanguageENThrowsExceptionWhenStabilityInputIsNull()
{
var kernelWrapper = new MacroStabilityInwardsKernelWrapper();
Assert.That(() => kernelWrapper.Execute(null, null, out _), Throws.InstanceOf().With.Message.EqualTo("No input object defined for Macro Stability"));
}
[Test]
[SetUICulture("nl-NL")]
public void TestThrowsExceptionWhenStabilityOutputIsNull()
{
var kernelWrapper = new MacroStabilityInwardsKernelWrapper();
Assert.That(() => kernelWrapper.PostProcess(new DamKernelInput(), null, null, "", out _), Throws.InstanceOf().With.Message.EqualTo("Geen uitvoer object gedefinieerd voor Macrostabiliteit"));
}
[Test]
[SetUICulture("nl-NL")]
public void TestThrowsExceptionWhenDamKernelInputIsNull()
{
var kernelWrapper = new MacroStabilityInwardsKernelWrapper();
Assert.That(() => kernelWrapper.PostProcess(null, null, null, "", out _), Throws.InstanceOf().With.Message.EqualTo("Geen Dam invoer object gedefinieerd voor Macrostabiliteit"));
}
private static DamKernelInput CreateDamKernelInputForTest()
{
Location location = DamEngineDataTestFactory.CreateLocation(FactoryForSurfaceLines.CreateSurfaceLineTutorial1());
// Correction needed in order to make surface line as lengthy as needed to perform a proper calculation.
location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X = 100;
// Correction needed in order to make surface line points strictly increasing increasing (ditch was vertical at polderside,
// now this not allowed by the kernel validator!) So that needs to be fixed in the kernel).
location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X = 62.5;
location.SurfaceLine.Geometry.SyncCalcPoints();
SoilProfile1D soilProfile = DamEngineDataTestFactory.CreateSoilProfile1D(location.SoilList);
SetWaterpressureInterpolationModel(soilProfile.Layers);
// This test is based on a 1D profile, to be combined with the surface line.
var subSoilScenario = new SoilGeometryProbability
{
SoilProfileType = SoilProfileType.ProfileType1D,
StiFileName = "",
FullStiFileName = "",
SoilProfile2D = null,
SegmentFailureMechanismType = SegmentFailureMechanismType.Stability,
SoilProfile1D = soilProfile
};
var damKernelInput = new DamKernelInput
{
FilenamePrefix = "Loc(TestLocation)_Sce(1)",
CalculationDir = "..\\Test",
Location = location,
SubSoilScenario = subSoilScenario,
RiverLevelLow = null,
DamFailureMechanismeCalculationSpecification = new DamFailureMechanismeCalculationSpecification()
};
SlipCircleDefinition sd = damKernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab
.MStabParameters.SlipCircleDefinition;
sd.UpliftVanLeftGridHorizontalPointCount = 3;
sd.UpliftVanLeftGridVerticalPointCount = 3;
sd.UpliftVanLeftGridHorizontalPointDistance = 1;
sd.UpliftVanLeftGridVerticalPointDistance = 1;
sd.UpliftVanRightGridHorizontalPointCount = 3;
sd.UpliftVanRightGridVerticalPointCount = 3;
sd.UpliftVanRightGridHorizontalPointDistance = 1;
sd.UpliftVanRightGridVerticalPointDistance = 1;
sd.UpliftVanTangentLinesDefinition = TangentLinesDefinition.OnBoundaryLines;
sd.UpliftVanTangentLinesDistance = 1;
sd.GridSizeDetermination = GridSizeDetermination.Specified;
damKernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.Model =
MStabModelType.UpliftVan;
return damKernelInput;
}
private static void SetWaterpressureInterpolationModel(IEnumerable layers)
{
foreach (SoilLayer1D layer in layers)
{
layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Hydrostatic;
}
}
}