Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/EngineToMacroStabilityKernelOutputTests.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/EngineToMacroStabilityKernelOutputTests.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/EngineToMacroStabilityKernelOutputTests.cs (revision 6366) @@ -0,0 +1,27 @@ +// 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. + +namespace Deltares.DamEngine.Calculators.Tests.KernelWrappers.MacroStabilityCommon.MacroStabilityIo; + +public class EngineToMacroStabilityKernelOutputTests +{ + +} \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillEngineFromMacroStabilityKernelOutput.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillEngineFromMacroStabilityKernelOutput.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillEngineFromMacroStabilityKernelOutput.cs (revision 6366) @@ -0,0 +1,33 @@ +// 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; +using Deltares.MacroStability.Io.XmlOutput; + +namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo; + +public class FillEngineFromMacroStabilityKernelOutput +{ + public void FillDamProjectDataFromKernelModel(FullOutputModelType macroStabilityOutput) + { + throw new NotImplementedException("This method is not implemented yet."); + } +} \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillEngineFromMacroStabilityKernelInput.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillEngineFromMacroStabilityKernelInput.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillEngineFromMacroStabilityKernelInput.cs (revision 6366) @@ -0,0 +1,34 @@ +// 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; +using Deltares.MacroStability.Io.XmlInput; + +namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo; + +public class FillEngineFromMacroStabilityKernelInput +{ + public void FillDamProjectDataFromKernelModel(FullInputModelType macroStabilityInput) + { + throw new NotImplementedException("This method is not implemented yet."); + } + +} \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityDirectIoTests.cs =================================================================== diff -u -r6360 -r6366 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityDirectIoTests.cs (.../MacroStabilityDirectIoTests.cs) (revision 6360) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityDirectIoTests.cs (.../MacroStabilityDirectIoTests.cs) (revision 6366) @@ -89,16 +89,16 @@ DamFailureMechanismeCalculationSpecification = expectedDamProjectData.DamProjectCalculationSpecification.CurrentSpecification }; var fillMacroStabilityInterfaceInputFromEngine = new FillMacroStabilityInterfaceInputFromEngine(); - fillMacroStabilityInterfaceInputFromEngine.UpliftVanCalculationGrid = expectedUpliftVanCalculationGrid; + fillMacroStabilityInterfaceInputFromEngine.UpliftVanCalculationGrid = expectedUpliftVanCalculationGrid; // TODO The: this is not correct, it should be filled in CreateMacroStabilityInterface() MacroStabilityInterface macroStabilityInterface = fillMacroStabilityInterfaceInputFromEngine.CreateMacroStabilityInterface( damKernelInput, expectedParametersMStab.MStabParameters, expectedWaternet); + + // get the Macrostability kernel model KernelModel kernelModel = macroStabilityInterface.KernelModel; - // get the input for the CSharp wrapper - // MacroStabilityInput expectedMacrostabilityInput = - // fillMacroStabilityWrapperInputFromEngine.CreateMacroStabilityInput(damKernelInput, expectedParametersMStab.MStabParameters, expectedWaternet); + fillMacroStabilityWrapperInputFromEngine.CreateMacroStabilityInput(damKernelInput, expectedParametersMStab.MStabParameters, expectedWaternet); // // reverse that input to the engine data - // var fillEngineFromMacroStabilityWrapperInput = new FillEngineFromMacroStabilityWrapperInput(); - // fillEngineFromMacroStabilityWrapperInput.FillDamProjectDataFromKernelModel(expectedMacrostabilityInput); + var fillEngineFromMacroStabilityWrapperInput = new FillEngineFromMacroStabilityWrapperInput(); + //fillEngineFromMacroStabilityWrapperInput.FillDamProjectDataFromKernelModel(expectedMacrostabilityInput); // // // Then the data models are equal // CompareStabilityModel(expectedParametersMStab, fillEngineFromMacroStabilityWrapperInput.FailureMechanismParametersMStab); Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillMacroStabilityKernelOutputFromEngine.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillMacroStabilityKernelOutputFromEngine.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillMacroStabilityKernelOutputFromEngine.cs (revision 6366) @@ -0,0 +1,35 @@ +// 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; +using Deltares.DamEngine.Calculators.KernelWrappers.Common; +using Deltares.DamEngine.Data.General; +using Deltares.MacroStability.Io.XmlOutput; + +namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo; + +public class FillMacroStabilityKernelOutputFromEngine +{ + public FullOutputModelType CreateFullOutputModel() + { + throw new NotImplementedException("This method is not implemented yet."); + } +} \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/EngineToMacroStabilityKernelInputTests.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/EngineToMacroStabilityKernelInputTests.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/EngineToMacroStabilityKernelInputTests.cs (revision 6366) @@ -0,0 +1,622 @@ +// 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; +using System.Collections.Generic; +using System.Linq; +using Deltares.DamEngine.Calculators.KernelWrappers.Common; +using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon; +using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo; +using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.Geometry; +using Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.TestHelpers; +using Deltares.DamEngine.TestHelpers.Factories; +using Deltares.MacroStability.Interface; +using Deltares.MacroStability.Io.XmlInput; +using Deltares.MacroStability.Kernel; +using KellermanSoftware.CompareNetObjects; +using NUnit.Framework; +using CharacteristicPointType = Deltares.DamEngine.Data.Geotechnics.CharacteristicPointType; +using Point2D = Deltares.DamEngine.Data.Geometry.Point2D; +using Soil = Deltares.DamEngine.Data.Geotechnics.Soil; +using UpliftVanCalculationGrid = Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.UpliftVanCalculationGrid; + +namespace Deltares.DamEngine.Calculators.Tests.KernelWrappers.MacroStabilityCommon.MacroStabilityIo; + +[TestFixture] +public class EngineToMacroStabilityKernelInputTests +{ + private static readonly List soilParametersToIgnore = + [ + "RRatio", + "RheologicalCoefficient", + "BondStressCurve", + "UseSoilType", + "UseDefaultShearStrengthModel" + ]; + + [Test] + public void GivenDamEngineDataModelWhenGoingToAndFromKernelInputThenDataIsEqual() + { + // Given DamEngine data (DamProjectData) + DamProjectData expectedDamProjectData = FactoryForDamProjectData.CreateExampleDamProjectData(); + expectedDamProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications[0] + .StabilityModelType = StabilityModelType.UpliftVan; + Waternet expectedWaternet = CreateExampleWaternet(); + UpliftVanCalculationGrid expectedUpliftVanCalculationGrid = CreateExampleUpliftVanCalculationGrid(); + + Location expectedLocation = expectedDamProjectData.Dike.Locations[0]; + SoilList expectedSoilList = expectedDamProjectData.Dike.SoilList; + SoilProfile2D expectedSoilProfile2D = expectedLocation.Segment.SoilProfileProbabilities[0].SoilProfile2D; + SurfaceLine2 expectedSurfaceLine2D = expectedLocation.SurfaceLine; + IList expectedConsolidationValues = expectedLocation.TrafficLoadDegreeOfConsolidations; + FailureMechanismParametersMStab expectedParametersMStab = expectedDamProjectData.DamProjectCalculationSpecification.CurrentSpecification.FailureMechanismParametersMStab; + var expectedTrafficLoad = new TrafficLoad + { + Pressure = 6.0, + XStart = expectedSurfaceLine2D.CharacteristicPoints.GetPoint2D(CharacteristicPointType.TrafficLoadInside).X, + XEnd = expectedSurfaceLine2D.CharacteristicPoints.GetPoint2D(CharacteristicPointType.TrafficLoadOutside).X + }; + var damKernelInput = new DamKernelInput + { + SubSoilScenario = expectedLocation.Segment.SoilProfileProbabilities[0], + Location = expectedLocation, + DamFailureMechanismeCalculationSpecification = expectedDamProjectData.DamProjectCalculationSpecification.CurrentSpecification + }; + + var fillMacroStabilityKernelInputFromEngine = new FillMacroStabilityKernelInputFromEngine + { + UpliftVanCalculationGrid = expectedUpliftVanCalculationGrid, + TrafficLoad = expectedTrafficLoad + }; + + fillMacroStabilityKernelInputFromEngine.UpliftVanCalculationGrid = expectedUpliftVanCalculationGrid; // TODO The: this is not correct, it should be filled in CreateMacroStabilityInterface() + + // Create the Macrostability kernel model + FullInputModelType fullInputModel = fillMacroStabilityKernelInputFromEngine.CreateFullInputModel( + damKernelInput, expectedParametersMStab.MStabParameters, expectedWaternet); + Assert.That(fullInputModel, Is.Not.Null); + // // reverse that input to the engine data + // var fillEngineFromMacroStabilityWrapperInput = new FillEngineFromMacroStabilityWrapperInput(); + //fillEngineFromMacroStabilityWrapperInput.FillDamProjectDataFromKernelModel(expectedMacrostabilityInput); + // + // // Then the data models are equal + // CompareStabilityModel(expectedParametersMStab, fillEngineFromMacroStabilityWrapperInput.FailureMechanismParametersMStab); + // CompareSoilModel(expectedSoilList, fillEngineFromMacroStabilityWrapperInput.SoilList); + // CompareSoilProfile2D(expectedSoilProfile2D, fillEngineFromMacroStabilityWrapperInput.SoilProfile2D); + // CompareSurfaceLine(expectedSurfaceLine2D, fillEngineFromMacroStabilityWrapperInput.SurfaceLine2); + // CompareTrafficLoad(expectedTrafficLoad, fillEngineFromMacroStabilityWrapperInput.TrafficLoad); + // CompareTrafficLoadDegreeOfConsolidations(expectedConsolidationValues, fillEngineFromMacroStabilityWrapperInput.TrafficLoadDegreeOfConsolidations); + // SlipCircleDefinition expectedUpliftVanCalculationGridSettings = expectedParametersMStab.MStabParameters.SlipCircleDefinition; + // CompareUpliftVanCalculationGridSettings(expectedUpliftVanCalculationGridSettings, + // fillEngineFromMacroStabilityWrapperInput.SlipCircleDefinition); + // + // bool isAutoTangentLine = expectedUpliftVanCalculationGridSettings.UpliftVanTangentLinesDefinition == TangentLinesDefinition.Specified; + // CompareUpliftVanCalculationGrid(expectedUpliftVanCalculationGrid, fillEngineFromMacroStabilityWrapperInput.UpliftVanCalculationGrid, isAutoTangentLine); + // CompareWaternet(expectedWaternet, fillEngineFromMacroStabilityWrapperInput.Waternet); + // //Todo : add and or implement comparer per item as these are added to the code + } + + [TestCase(1)] + [TestCase(2)] + [TestCase(3)] + public void GivenCSharpWrapperOutputWhenGoingToAndFromEngineTheDataIsEqual(int testNumber) + { + //ToDo fill this + // MacroStabilityOutput expectedKernelOutput = CreateKernelOutputForTest(testNumber); + // var engineOutput = new Calculators.KernelWrappers.MacroStabilityInwards.MacroStabilityOutput(); + // FillEngineFromMacroStabilityWrapperOutput.FillEngineDataWithResults(expectedKernelOutput, engineOutput, out List logMessages); + // MacroStabilityOutput kernelOutput = FillMacroStabilityWrapperOutputFromEngine.FillMacroStabilityWrapperOutput(engineOutput, logMessages); + + var compare = new CompareLogic + { + Config = + { + MaxDifferences = 100 + } + }; + // ComparisonResult result = compare.Compare(expectedKernelOutput, kernelOutput); + // Assert.That(result.Differences, Is.Empty, "Differences found read/write kernel Output"); + } + + private static UpliftVanCalculationGrid CreateExampleUpliftVanCalculationGrid() + { + var random = new Random(21); + var upliftVanCalculationGrid = new UpliftVanCalculationGrid + { + LeftGridXLeft = random.NextDouble(), + LeftGridXRight = random.NextDouble(), + LeftGridZTop = random.NextDouble(), + LeftGridZBottom = random.NextDouble(), + LeftGridXCount = random.Next(), + LeftGridZCount = random.Next(), + RightGridXLeft = random.NextDouble(), + RightGridXRight = random.NextDouble(), + RightGridZTop = random.NextDouble(), + RightGridZBottom = random.NextDouble(), + RightGridXCount = random.Next(), + RightGridZCount = random.Next(), + TangentLinesCreationMethod = TangentLinesDefinition.OnBoundaryLines, + TangentLineZBottom = 0, + TangentLineZTop = 10, + TangentLineCount = 10 + }; + return upliftVanCalculationGrid; + } + + private static Waternet CreateExampleWaternet() + { + var waterNet = new Waternet + { + IsGenerated = false, + UnitWeight = 9.81, + Name = "Test Waternet" + }; + + var random = new Random(21); + var phreaticLine = new PhreaticLine + { + Name = "Test Phreatic line" + }; + waterNet.PhreaticLine = phreaticLine; + SetGeometry(phreaticLine, random.Next()); + + // Head line + const int nrOfHeadLines = 10; + for (var i = 0; i < nrOfHeadLines; i++) + { + var headLine = new HeadLine + { + Name = $"Test Head line{i}" + }; + SetGeometry(headLine, random.Next()); + waterNet.HeadLineList.Add(headLine); + } + + // Waternet line + for (var i = 0; i < nrOfHeadLines; i++) + { + var waternetLine = new WaternetLine + { + Name = $"Test Waternet line {i}", + HeadLine = waterNet.HeadLineList[i] + }; + SetGeometry(waternetLine, random.Next()); + waterNet.WaternetLineList.Add(waternetLine); + } + + return waterNet; + } + + private static void SetGeometry(GeometryPointString geometry, int seed) + { + var random = new Random(seed); + for (var i = 0; i < 10; i++) + { + geometry.Points.Add(new Point2D(random.NextDouble(), random.NextDouble())); + } + } + + private static void CompareTrafficLoad(TrafficLoad expectedTrafficLoad, TrafficLoad actualTrafficLoad) + { + var compare = new CompareLogic + { + Config = + { + MaxDifferences = 100 + } + }; + compare.Config.MembersToInclude = new List + { + "XEnd", + "XStart", + "Pressure" + }; + ComparisonResult result = compare.Compare(expectedTrafficLoad, actualTrafficLoad); + Assert.That(result.Differences, Is.Empty, "Differences found read/write kernel Traffic Load"); + } + + private static void CompareTrafficLoadDegreeOfConsolidations(IList expectedDegreeOfConsolidations, IList actualDegreeOfConsolidation) + { + int expectedNrOfDegreeOfConsolidation = expectedDegreeOfConsolidations.Count; + Assert.That(actualDegreeOfConsolidation, Has.Count.EqualTo(expectedNrOfDegreeOfConsolidation)); + + var compare = new CompareLogic + { + Config = + { + MaxDifferences = 100 + } + }; + for (var i = 0; i < expectedNrOfDegreeOfConsolidation; i++) + { + + compare.Config.MembersToInclude = new List + { + "Consolidator", + "Consolidated", + "Value" + }; + ComparisonResult result = compare.Compare(expectedDegreeOfConsolidations, actualDegreeOfConsolidation); + Assert.That(result.Differences, Is.Empty, "Differences found read/write kernel Consolidation Values"); + } + } + + private static void CompareUpliftVanCalculationGridSettings(SlipCircleDefinition expectedSlipCircleDefinition, + SlipCircleDefinition actualSlipCircleDefinition) + { + Assert.That(actualSlipCircleDefinition.UpliftVanGridSizeDetermination, Is.EqualTo(expectedSlipCircleDefinition.UpliftVanGridSizeDetermination)); + Assert.That(actualSlipCircleDefinition.UpliftVanTangentLinesDefinition, Is.EqualTo(expectedSlipCircleDefinition.UpliftVanTangentLinesDefinition)); + // Note: do not test UpliftVanTangentLinesDistance as there is no way to be sure of equal values as determination to and from involves rounding. + //Assert.AreEqual(expectedSlipCircleDefinition.UpliftVanTangentLinesDistance, actualSlipCircleDefinition.UpliftVanTangentLinesDistance); + } + + private static void CompareUpliftVanCalculationGrid(UpliftVanCalculationGrid expectedSlipPlaneUpliftVan, + UpliftVanCalculationGrid actualSlipPlaneUpliftVan, bool isAutoTangentLine) + { + Assert.Multiple(() => + { + Assert.That(actualSlipPlaneUpliftVan.LeftGridXLeft, Is.EqualTo(expectedSlipPlaneUpliftVan.LeftGridXLeft)); + Assert.That(actualSlipPlaneUpliftVan.LeftGridXRight, Is.EqualTo(expectedSlipPlaneUpliftVan.LeftGridXRight)); + Assert.That(actualSlipPlaneUpliftVan.LeftGridZTop, Is.EqualTo(expectedSlipPlaneUpliftVan.LeftGridZTop)); + Assert.That(actualSlipPlaneUpliftVan.LeftGridZBottom, Is.EqualTo(expectedSlipPlaneUpliftVan.LeftGridZBottom)); + Assert.That(actualSlipPlaneUpliftVan.LeftGridXCount, Is.EqualTo(expectedSlipPlaneUpliftVan.LeftGridXCount)); + Assert.That(actualSlipPlaneUpliftVan.LeftGridZCount, Is.EqualTo(expectedSlipPlaneUpliftVan.LeftGridZCount)); + + Assert.That(actualSlipPlaneUpliftVan.RightGridXLeft, Is.EqualTo(expectedSlipPlaneUpliftVan.RightGridXLeft)); + Assert.That(actualSlipPlaneUpliftVan.RightGridXRight, Is.EqualTo(expectedSlipPlaneUpliftVan.RightGridXRight)); + Assert.That(actualSlipPlaneUpliftVan.RightGridZTop, Is.EqualTo(expectedSlipPlaneUpliftVan.RightGridZTop)); + Assert.That(actualSlipPlaneUpliftVan.RightGridZBottom, Is.EqualTo(expectedSlipPlaneUpliftVan.RightGridZBottom)); + Assert.That(actualSlipPlaneUpliftVan.RightGridXCount, Is.EqualTo(expectedSlipPlaneUpliftVan.RightGridXCount)); + Assert.That(actualSlipPlaneUpliftVan.RightGridZCount, Is.EqualTo(expectedSlipPlaneUpliftVan.RightGridZCount)); + }); + + if (!isAutoTangentLine) + { + Assert.That(actualSlipPlaneUpliftVan.TangentLineLevels, Is.EqualTo(expectedSlipPlaneUpliftVan.TangentLineLevels).AsCollection); + } + } + + private static void CompareWaternet(Waternet expectedWaternet, Waternet actualWaternet) + { + Assert.That(actualWaternet.Name, Is.EqualTo(expectedWaternet.Name)); + CompareLine(expectedWaternet.PhreaticLine, actualWaternet.PhreaticLine); + CompareWaternetHeadLines(expectedWaternet.HeadLineList, actualWaternet.HeadLineList); + CompareWaternetLines(actualWaternet.WaternetLineList, expectedWaternet.WaternetLineList); + } + + private static void CompareWaternetLines(IEnumerable actualWaternetLines, + IEnumerable expectedWaternetLines) + { + int expectedNrOfWaternetLines = actualWaternetLines.Count(); + Assert.That(actualWaternetLines.Count(), Is.EqualTo(expectedNrOfWaternetLines)); + for (var i = 0; i < expectedNrOfWaternetLines; i++) + { + WaternetLine expectedWaternetLine = expectedWaternetLines.ElementAt(i); + WaternetLine actualWaternetLine = actualWaternetLines.ElementAt(i); + CompareLine(expectedWaternetLine, actualWaternetLine); + CompareLine(expectedWaternetLine.HeadLine, actualWaternetLine.HeadLine); + } + } + + private static void CompareWaternetHeadLines(IEnumerable expectedHeadLines, + IEnumerable actualHeadLines) + { + int expectedNrOfHeadLines = expectedHeadLines.Count(); + Assert.That(actualHeadLines.Count(), Is.EqualTo(expectedNrOfHeadLines)); + + for (var i = 0; i < expectedNrOfHeadLines; i++) + { + HeadLine expectedHeadLine = expectedHeadLines.ElementAt(i); + HeadLine actualHeadLine = actualHeadLines.ElementAt(i); + CompareLine(expectedHeadLine, actualHeadLine); + } + } + + private static void CompareLine(TLineType expectedHeadLine, TLineType actualHeadLine) + where TLineType : GeometryPointString + { + Assert.That(actualHeadLine.Name, Is.EqualTo(expectedHeadLine.Name)); + + List expectedPoints = expectedHeadLine.Points; + int expectedNrOfPoints = expectedPoints.Count; + List actualPoints = actualHeadLine.Points; + Assert.That(actualPoints, Has.Count.EqualTo(expectedNrOfPoints)); + for (var i = 0; i < expectedNrOfPoints; i++) + { + Point2D expectedCoordinate = expectedPoints[i]; + Point2D actualCoordinate = actualPoints[i]; + + Assert.That(expectedCoordinate.LocationEquals(actualCoordinate), Is.True); + } + } + + private static void CompareSurfaceLine(SurfaceLine2 expectedSurfaceLine2, SurfaceLine2 actualSurfaceLine2) + { + CharacteristicPointSet expectedCharacteristicPoints = expectedSurfaceLine2.CharacteristicPoints; + CharacteristicPointSet actualCharacteristicPoints = actualSurfaceLine2.CharacteristicPoints; + var compare = new CompareLogic + { + Config = + { + MaxDifferences = 100 + } + }; + compare.Config.MembersToIgnore = new List + { + "Owner" + }; + ComparisonResult result = compare.Compare(expectedCharacteristicPoints, actualCharacteristicPoints); + Assert.That(result.Differences, Is.Empty, "Differences found read/write kernel SurfaceLine"); + } + + private static void CompareSoilProfile2D(SoilProfile2D expectedSoilProfile, SoilProfile2D actualSoilProfile) + { + var compare = new CompareLogic + { + Config = + { + MaxDifferences = 100 + } + }; + compare.Config.MembersToIgnore = soilParametersToIgnore; + compare.Config.MembersToIgnore.Add("Name"); + ComparisonResult result = compare.Compare(expectedSoilProfile, actualSoilProfile); + Assert.That(result.Differences, Is.Empty, "Differences found read/write kernel SoilProfile2D"); + } + + private static void CompareSoilModel(SoilList expectedSoils, SoilList actualSoils) + { + Assert.That(actualSoils.Soils, Has.Count.EqualTo(expectedSoils.Soils.Count), "Soil Count does not match"); + foreach (Soil expectedSoil in expectedSoils.Soils) + { + Soil actualSoil = actualSoils.Soils.SingleOrDefault(soil => soil.Name.Equals(expectedSoil.Name)); + Assert.That(actualSoil, Is.Not.Null, $"Soil {expectedSoil.Name} not found"); + var compare = new CompareLogic + { + Config = + { + MaxDifferences = 100 + } + }; + compare.Config.MembersToIgnore = soilParametersToIgnore; + ComparisonResult result = compare.Compare(expectedSoil, actualSoil); + Assert.That(result.Differences, Is.Empty, "Differences found read/write kernel SoilModel"); + } + } + + private static void CompareStabilityModel(FailureMechanismParametersMStab expectedStabilityModel, FailureMechanismParametersMStab actualStabilityModel) + { + Assert.Multiple(() => + { + Assert.That(actualStabilityModel.MStabParameters.SearchMethod, Is.EqualTo(expectedStabilityModel.MStabParameters.SearchMethod)); + Assert.That(actualStabilityModel.MStabParameters.Model, Is.EqualTo(expectedStabilityModel.MStabParameters.Model)); + Assert.That(actualStabilityModel.MStabParameters.GridPosition, Is.EqualTo(expectedStabilityModel.MStabParameters.GridPosition)); + }); + } + + // private static MacroStabilityOutput CreateKernelOutputForTest(int choice) + // { + // var output = new MacroStabilityOutput(); + // var messagesOutput = new List(); + // if (choice == 1) + // { + // // Result 1: succeeded, has a SafetyFactor of ca. 3.856, no messages + // output.ResultType = CalculationResultType.Succeeded; + // output.PreprocessingOutputBase = new UpliftVanPreprocessingOutput(); + // output.StabilityOutput = new StabilityOutput + // { + // SafetyFactor = 3.856, + // ModelOptionType = StabilityModelOptionType.UpliftVan + // }; + // output.StabilityOutput.MinimumSafetyCurve = SetupUpliftDualSlidingCircle(); + // } + // else if (choice == 2) + // { + // // Result 2: succeeded, has a SafetyFactor of ca. 1.857, has info and warning, but no error messages + // messagesOutput.Clear(); + // var infoMessage = new Message(); + // infoMessage.Content = "Info"; + // infoMessage.MessageType = MessageType.Info; + // messagesOutput.Add(infoMessage); + // var warningMessage = new Message(); + // warningMessage.Content = "Warning"; + // warningMessage.MessageType = MessageType.Warning; + // messagesOutput.Add(warningMessage); + // output.ResultType = CalculationResultType.Succeeded; + // output.PreprocessingOutputBase = new UpliftVanPreprocessingOutput(); + // output.StabilityOutput = new StabilityOutput + // { + // SafetyFactor = 1.857, + // Messages = messagesOutput, + // ModelOptionType = StabilityModelOptionType.UpliftVan + // }; + // } + // else + // { + // // Result 3 failed - has a SafetyFactor of NaN, has an error message + // messagesOutput.Clear(); + // var errorMessage = new Message(); + // errorMessage.Content = "Error"; + // errorMessage.MessageType = MessageType.Error; + // messagesOutput.Add(errorMessage); + // output.StabilityOutput = new StabilityOutput(); + // output.ResultType = CalculationResultType.RunFailed; + // output.StabilityOutput.SafetyFactor = double.NaN; + // output.StabilityOutput.Messages = messagesOutput; + // } + // + // return output; + // } + // + // private static DualSlidingCircleMinimumSafetyCurve SetupUpliftDualSlidingCircle() + // { + // var dualSlidingCircleMinimumSafetyCurve = new DualSlidingCircleMinimumSafetyCurve + // { + // ActiveCircleCenter = new MacroStability.CSharpWrapper.Point2D(10, 10), + // ActiveCircleRadius = 8, + // PassiveCircleCenter = new MacroStability.CSharpWrapper.Point2D(22, 11), + // PassiveCircleRadius = 7 + // }; + // List slices = CreateSlices(); + // dualSlidingCircleMinimumSafetyCurve.Slices = slices; + // + // return dualSlidingCircleMinimumSafetyCurve; + // } + // + // private static List CreateSlices() + // { + // var slices = new List(); + // for (var i = 1; i < 6; i++) + // { + // var slice = new Slice + // { + // BottomLeftPoint = new MacroStability.CSharpWrapper.Point2D(-1 * i, 1 * i), + // BottomRightPoint = new MacroStability.CSharpWrapper.Point2D(-2 * i, 2 * i), + // TopLeftPoint = new MacroStability.CSharpWrapper.Point2D(-3 * i, 3 * i), + // TopRightPoint = new MacroStability.CSharpWrapper.Point2D(-4 * i, 4 * i), + // Name = "Slice" + i, + // POP = 1.11 * i, + // YieldStress = 2.22 * i, + // OCR = 3.33 * i, + // ResultantForce = 4.44 * i, + // ResultantMoment = 5.55 * i, + // ResultantAngle = 6.66 * i, + // CohesionInput = 7.77 * i, + // CohesionOutput = 8.88 * i, + // FrictionAngleInput = 9.99 * i, + // FrictionAngleOutput = 10.10 * i, + // DilatancyInput = 11.11 * i, + // SuInput = 12.12 * i, + // SuOutput = 13.13 * i, + // ShearStrengthModelType = ShearStrengthModelType.MohrCoulomb, + // ShearStressInput = 14.14 * i, + // ShearStressOutput = 15.15 * i, + // Weight = 16.16 * i, + // TotalPorePressure = 17.17 * i, + // EffectiveStress = 18.18 * i, + // HydrostaticPorePressure = 19.19 * i, + // PiezometricPorePressure = 20.20 * i, + // ExcessPorePressure = 21.21 * i, + // DegreeOfConsolidationPorePressure = 22.22 * i, + // PorePressureDueToDegreeOfConsolidationLoad = 23.23 * i, + // LoadStress = 24.24 * i, + // SoilStress = 25.25 * i, + // TotalStress = 26.26 * i, + // PorePressure = 27.27 * i, + // VerticalPorePressure = 28.28 * i, + // HorizontalPorePressure = 29.29 * i, + // ExternalLoad = 30.30 * i, + // NormalStress = 31.31 * i, + // LeftForce = 32.32 * i, + // LeftForceY = 33.33 * i, + // LeftForceAngle = 34.34 * i, + // RightForce = 35.35 * i, + // RightForceY = 36.36 * i, + // RightForceAngle = 37.37 * i, + // HorizontalSoilQuakeStress = 38.38 * i, + // VerticalSoilQuakeStress = 39.39 * i, + // WaterQuakeStress = 40.40 * i, + // RatioCuPc = 41.41 * i, + // StrengthIncreaseExponent = 42.42 * i, + // UpliftFactor = 43.43 * i, + // UpliftReductionFactor = 44.44 * i, + // ArcLength = 45.45 * i, + // BottomAngle = 46.46 * i, + // TopAngle = 47.47 * i, + // Width = 48.48 * i + // }; + // slices.Add(slice); + // } + // + // return slices; + // } + // + // public class GivenDamKernelInput + // { + // private readonly DamKernelInput damKernelInput = CreateDamKernelInputWithForbiddenZone(); + // + // [Test] + // [TestCase(0.0, 5.0)] + // [TestCase(0.2, 6.0)] + // [TestCase(1.0, 10.0)] + // public void WithForbiddenZone_WhenTransferSlipPlaneConstraints_ThenSlipPlaneConstraintsAreSet(double forbiddenZoneFactor,double xEntryMax) + // { + // damKernelInput.Location.StabilityOptions.ForbiddenZoneFactor = forbiddenZoneFactor; + // var macroStabilityInput = new MacroStabilityInput(); + // // When + // FillMacroStabilityWrapperInputFromEngine.TransferSlipPlaneConstraints(damKernelInput.Location, macroStabilityInput.StabilityModel.SlipPlaneConstraints); + // Assert.Multiple(() => + // { + // // Then + // Assert.That(macroStabilityInput.StabilityModel.SlipPlaneConstraints.SlipPlaneMinDepth, Is.EqualTo(1.5)); + // Assert.That(macroStabilityInput.StabilityModel.SlipPlaneConstraints.XEntryMin, Is.EqualTo(1.0)); + // Assert.That(macroStabilityInput.StabilityModel.SlipPlaneConstraints.XEntryMax, Is.EqualTo(xEntryMax)); + // }); + // } + // + // [Test] + // public void WithNoZones_WhenTransferSlipPlaneConstraints_ThenXEntryIsNotSet() + // { + // damKernelInput.Location.StabilityOptions.StabilityZoneType = StabilityZoneType.NoZones; + // var macroStabilityInput = new MacroStabilityInput(); + // // When + // FillMacroStabilityWrapperInputFromEngine.TransferSlipPlaneConstraints(damKernelInput.Location, macroStabilityInput.StabilityModel.SlipPlaneConstraints); + // Assert.Multiple(() => + // { + // // Then + // Assert.That(macroStabilityInput.StabilityModel.SlipPlaneConstraints.SlipPlaneMinDepth, Is.EqualTo(1.5)); + // Assert.That(macroStabilityInput.StabilityModel.SlipPlaneConstraints.XEntryMin, Is.NaN); + // Assert.That(macroStabilityInput.StabilityModel.SlipPlaneConstraints.XEntryMax, Is.NaN); + // }); + // } + // + // private static DamKernelInput CreateDamKernelInputWithForbiddenZone() + // { + // var surfaceLine = new SurfaceLine2() + // { + // CharacteristicPoints = + // { + // GeometryMustContainPoint = true + // }, + // Geometry = new GeometryPointString() + // }; + // surfaceLine.EnsurePointOfType(1.0, 0, CharacteristicPointType.DikeTopAtRiver); + // surfaceLine.EnsurePointOfType(5.0, 0, CharacteristicPointType.DikeTopAtPolder); + // surfaceLine.EnsurePointOfType(10.0, 0, CharacteristicPointType.DikeToeAtPolder); + // var damKernelInput = new DamKernelInput + // { + // Location = new Location() + // { + // SurfaceLine = surfaceLine, + // StabilityOptions = new StabilityOptions + // { + // MinimalCircleDepth = 1.5, + // StabilityZoneType = StabilityZoneType.ForbiddenZone, + // ForbiddenZoneFactor = 0.2 + // } + // } + // }; + // return damKernelInput; + // } + // } +} \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillMacroStabilityKernelInputFromEngine.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillMacroStabilityKernelInputFromEngine.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityIo/FillMacroStabilityKernelInputFromEngine.cs (revision 6366) @@ -0,0 +1,472 @@ +// 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; +using System.Linq; +using Deltares.DamEngine.Calculators.KernelWrappers.Common; +using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.Geotechnics; +using Deltares.MacroStability.Io.XmlInput; +using CharacteristicPoint = Deltares.DamEngine.Data.Geotechnics.CharacteristicPoint; +using CharacteristicPointSet = Deltares.DamEngine.Data.Geotechnics.CharacteristicPointSet; +using CharacteristicPointType = Deltares.DamEngine.Data.Geotechnics.CharacteristicPointType; +using GeometryCurve = Deltares.DamEngine.Data.Geometry.GeometryCurve; +using GeometryLoop = Deltares.DamEngine.Data.Geometry.GeometryLoop; +using GeometrySurface = Deltares.DamEngine.Data.Geometry.GeometrySurface; +using Point2D = Deltares.DamEngine.Data.Geometry.Point2D; +using PreConsolidationStress = Deltares.DamEngine.Data.Geotechnics.PreConsolidationStress; +using SoilLayer2D = Deltares.DamEngine.Data.Geotechnics.SoilLayer2D; +using SoilProfile2D = Deltares.DamEngine.Data.Geotechnics.SoilProfile2D; +using SoilProfileType = Deltares.MacroStability.Io.XmlInput.SoilProfileType; +using SoilType = Deltares.MacroStability.Io.XmlInput.SoilType; +using SurfaceLine2 = Deltares.DamEngine.Data.Geotechnics.SurfaceLine2; +using Waternet = Deltares.DamEngine.Data.Geometry.Waternet; + +namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo; + +public class FillMacroStabilityKernelInputFromEngine +{ + /// Gets or sets the UpliftVan calculation grid. + /// The uplift van calculation grid. + public UpliftVanCalculationGrid UpliftVanCalculationGrid { get; set; } + + /// Gets or sets the Bishop calculation grid. + /// The bishop calculation grid. + public BishopCalculationGrid BishopCalculationGrid { get; set; } + + /// Gets or sets the traffic load. + /// The traffic load. + public TrafficLoad TrafficLoad { get; set; } + + public FullInputModelType CreateFullInputModel(DamKernelInput damKernelInput, MStabParameters mStabParameters, Waternet waterNet) + { + // The objectregistry is to be used to keep track of all keys of some of the referenced objects, see the C#wrapper for where and when to use it (Creators) + var objectRegistry = new ObjectRegistry(); + var fullInputModelType = new FullInputModelType + { + PreprocessingInput = TransferPreprocessingInput(damKernelInput, mStabParameters), + StabilityModel = TransferStabilityModel(damKernelInput, mStabParameters, objectRegistry), + VersionInfo = TransferVersionInfo() + }; + return fullInputModelType; + } + + private PreprocessingInputType TransferPreprocessingInput(DamKernelInput damKernelInput, MStabParameters mStabParameters) + { + if (damKernelInput == null) + { + return null; + } + + var preprocessingInputType = new PreprocessingInputType + { + PreConstructionStages = new PreConstructionStageType[1] + }; + preprocessingInputType.PreConstructionStages[0] = new PreConstructionStageType(); + PreConstructionStageType preConstructionLastStage = preprocessingInputType.PreConstructionStages.Last(); + preConstructionLastStage.Surfaceline = new SurfaceLineType(); + preConstructionLastStage.CreateWaternet = false; // #Bka: I can NOT find any use of this at the engine side so this must be false! + TransferSurfaceLine(damKernelInput.Location.SurfaceLine, preConstructionLastStage.Surfaceline); + + preprocessingInputType.SearchAreaConditions = TransferSearchAreaCondition(damKernelInput, mStabParameters); + + return preprocessingInputType; + } + + private SearchAreaConditionsType TransferSearchAreaCondition(DamKernelInput damKernelInput, MStabParameters mStabParameters) + { + var preprocessingSearchAreaConditions = new SearchAreaConditionsType + { + AutoGeneticAlgorithmOptions = false, //#Bka or true? is not to be found at engine side; or just set specified to false!? + AutoGeneticAlgorithmOptionsSpecified = true, + AutoLevenbergMarquardtOptions = false, //#Bka or true? is not to be found at engine side; or just set specified to false!? + AutoLevenbergMarquardtOptionsSpecified = true, + AutoSearchAreaSpecified = true, + AutoTangentLinesSpecified = true, + AutomaticForbiddenZones = false, //#Bka or true? is not to be found at engine side; or just set specified to false!? + AutomaticForbiddenZonesSpecified = true, + MaxSpacingBetweenBoundaries = 0.8, + MaxSpacingBetweenBoundariesSpecified = true, + OnlyAbovePleistoceenSpecified = true, + SlipPlanePosition = SearchAreaConditionsTypeSlipPlanePosition.High, //#Bka = default in C#wrapper, is not to be found at engine side; or just set specified to false!? + SlipPlanePositionSpecified = true, + TangentLineNumberSpecified = true, + TangentLineZBottomSpecified = true, + TangentLineZTopSpecified = true + }; + + switch (mStabParameters.Model) + { + case StabilityModelType.Bishop: + TransferBishopSearchAreaSettings(preprocessingSearchAreaConditions); + //BishopCalculationCircle = TransferBishopCalculationGrid(); #Bka, moet naar TransferStabilityModel want geen deel van TransferPreprocessingInput + break; + case StabilityModelType.UpliftVan: + TransferUpliftVanSearchAreaSettings(preprocessingSearchAreaConditions); + //UpliftVanCalculationGrid = TransferUpliftVanCalculationGrid(); #Bka, toevoegen en moet naar TransferStabilityModel want geen deel van TransferPreprocessingInput + break; + default: + throw new NotImplementedException(nameof(mStabParameters.Model)); + } + + return preprocessingSearchAreaConditions; + } + + private void TransferBishopSearchAreaSettings(SearchAreaConditionsType searchAreaConditions) + { + // In the Macrostability kernel, for Bishop, the automatic tangent lines are set by AutoSearchArea = True. + // Setting AutoTangentLines to true will create the automatic tangent lines of Uplift-Van which is not desired. + searchAreaConditions.AutoTangentLines = false; + searchAreaConditions.AutoSearchArea = BishopCalculationGrid.IsSearchAreaAutomatic; + searchAreaConditions.TangentLineNumber = BishopCalculationGrid.TangentLineCount; + searchAreaConditions.TangentLineZTop = BishopCalculationGrid.TangentLineZTop; + searchAreaConditions.TangentLineZBottom = BishopCalculationGrid.TangentLineZBottom; + } + + private void TransferUpliftVanSearchAreaSettings(SearchAreaConditionsType kernelSearchAreaConditions) + { + kernelSearchAreaConditions.AutoTangentLines = UpliftVanCalculationGrid.TangentLinesCreationMethod is TangentLinesDefinition.Automatic or TangentLinesDefinition.OnBoundaryLines; + kernelSearchAreaConditions.AutoSearchArea = UpliftVanCalculationGrid.IsGridsAutomatic; + kernelSearchAreaConditions.OnlyAbovePleistoceen = UpliftVanCalculationGrid.TangentLinesCreationMethod == TangentLinesDefinition.Automatic; + kernelSearchAreaConditions.MaxSpacingBetweenBoundaries = 0.8; + kernelSearchAreaConditions.TangentLineNumber = UpliftVanCalculationGrid.TangentLineCount; + kernelSearchAreaConditions.TangentLineZTop = UpliftVanCalculationGrid.TangentLineZTop; + kernelSearchAreaConditions.TangentLineZBottom = UpliftVanCalculationGrid.TangentLineZBottom; + } + + private BishopCalculationCircle TransferBishopCalculationGrid() + { + if (BishopCalculationGrid == null) + { + throw new ArgumentNullException(nameof(BishopCalculationGrid)); + } + + var kernelBishopCalculationCircle = new BishopCalculationCircle + { + Grid = new CalculationGridType + { + GridXNumber = BishopCalculationGrid.GridXCount, + GridXLeft = BishopCalculationGrid.GridXLeft, + GridXRight = BishopCalculationGrid.GridXRight, + GridZNumber = BishopCalculationGrid.GridZCount, + GridZTop = BishopCalculationGrid.GridZTop, + GridZBottom = BishopCalculationGrid.GridZBottom + } + }; + + if (!BishopCalculationGrid.IsSearchAreaAutomatic) + { + kernelBishopCalculationCircle.TangentLines = new double[BishopCalculationGrid.TangentLineLevels.Count]; + kernelBishopCalculationCircle.TangentLines = BishopCalculationGrid.TangentLineLevels.ToArray(); + } + + return kernelBishopCalculationCircle; + } + + private void TransferSurfaceLine(SurfaceLine2 surfaceLineInput, SurfaceLineType surfaceLine) + { + surfaceLine.CharacteristicPoints = new SurfaceLineTypeCharacteristicPoint[surfaceLineInput.CharacteristicPoints.Count]; + var i = 0; + foreach (CharacteristicPoint damCharPoint in surfaceLineInput.CharacteristicPoints) + { + var kernelCharPoint = new SurfaceLineTypeCharacteristicPoint + { + CharacteristicPointType = InterfaceConversionHelper.ConvertToMacroStabilityCharacteristicPointType(damCharPoint.CharacteristicPointType), + GeometryPoint = new Point2DType + { + X = damCharPoint.Point.X, + Z = damCharPoint.Point.Z + } + }; + surfaceLine.CharacteristicPoints[i] = kernelCharPoint; + i++; + } + } + + private StabilityInputType TransferStabilityModel(DamKernelInput damKernelInput, MStabParameters mStabParameters, ObjectRegistry objectRegistry) + { + if (damKernelInput == null || mStabParameters == null) + { + return null; + } + + var stabilityInputType = new StabilityInputType + { + UpliftVanCalculationGrid = new UpliftVanCalculationGridType(), + ConstructionStages = new ConstructionStageInputType[1], + SlipPlaneConstraints = new SlipPlaneConstraintsType() + }; + stabilityInputType.ConstructionStages[0] = new ConstructionStageInputType(); + ConstructionStageInputType lastStage = stabilityInputType.ConstructionStages.Last(); + + TransferStabilityModelProperties(mStabParameters, stabilityInputType); + TransferSlipPlaneConstraints(damKernelInput.Location, stabilityInputType.SlipPlaneConstraints); + stabilityInputType.Soils = new SoilType[damKernelInput.Location.SoilList.Soils.Count]; + lastStage.FixedSoilStresses = new FixedSoilStressType[damKernelInput.Location.SoilList.Soils.Count]; + TransferSoils(damKernelInput.Location.SoilList, stabilityInputType.Soils, lastStage.FixedSoilStresses, objectRegistry); + + lastStage.SoilProfile = new SoilProfileType(); + lastStage.PreconsolidationStresses = new PreconsolidationStressType[damKernelInput.SubSoilScenario.SoilProfile2D.PreconsolidationStresses.Count]; + lastStage.WaterDefinition = WaterDefinitionType.WaterNet; + TransferSoilProfile(damKernelInput.SubSoilScenario.SoilProfile2D, lastStage.SoilProfile, lastStage.PreconsolidationStresses, objectRegistry); + + return stabilityInputType; + } + + private VersionInfoType TransferVersionInfo() + { + var versionInfoType = new VersionInfoType + { + FileVersion = 2, + AssemblyVersion = "2.0.0.0", + AssemblyName = "Deltares.DamEngine" + }; + return versionInfoType; + } + + private void TransferStabilityModelProperties(MStabParameters mStabParameters, StabilityInputType kernelStabilityInput) + { + kernelStabilityInput.MoveGrid = true; // is not in DamEngine but MUST be true as we use the brute force approach. + kernelStabilityInput.MaximumSliceWidth = 1.0; // is not in DamEngine datamodel + // For Bishop, only Grid is possible however if Bishop/UpliftVan was selected, then the SearchAlgorithm concerns only Uplift-Van + kernelStabilityInput.SearchAlgorithm = mStabParameters.Model == StabilityModelType.Bishop ? SearchAlgorithmType.Grid : InterfaceConversionHelper.ConvertToMacroStabilitySearchMethod(mStabParameters.SearchMethod); + if (kernelStabilityInput.SearchAlgorithm == SearchAlgorithmType.BeeswarmAndLevenbergMarquardt) + { + CreateDefaultBeeSwarmOptions(kernelStabilityInput); + } + + kernelStabilityInput.ModelOption = InterfaceConversionHelper.ConvertToMacroStabilityModelOption(mStabParameters.Model); + kernelStabilityInput.Orientation = InterfaceConversionHelper.ConvertToMacroStabilityGridOrientation(mStabParameters.GridPosition); + kernelStabilityInput.NumberOfRefinementsGrid = 2; + kernelStabilityInput.NumberOfRefinementsTangentLines = 2; + } + + private static void TransferSlipPlaneConstraints(Location location, SlipPlaneConstraintsType slipPlaneConstraints) + { + if (location.StabilityOptions == null) + { + return; + } + + slipPlaneConstraints.SlipPlaneMinDepth = location.StabilityOptions.MinimalCircleDepth ?? 0.0; + if ((location.StabilityOptions.StabilityZoneType == StabilityZoneType.ForbiddenZone) && + location.StabilityOptions.ForbiddenZoneFactor.HasValue) + { + CharacteristicPointSet characteristicPoints = location.SurfaceLine.CharacteristicPoints; + slipPlaneConstraints.XEntryMin = characteristicPoints.GetPoint2D(CharacteristicPointType.DikeTopAtRiver).X; + double xDikeTopAtPolder = characteristicPoints.GetPoint2D(CharacteristicPointType.DikeTopAtPolder).X; + double xDikeToeAtPolder = characteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).X; + double factor = location.StabilityOptions.ForbiddenZoneFactor.Value; + slipPlaneConstraints.XEntryMax = (xDikeToeAtPolder * factor) + ((1 - factor) * xDikeTopAtPolder); + } + } + + private void CreateDefaultBeeSwarmOptions(StabilityInputType kernelStabilityInput) + { + kernelStabilityInput.BeeswarmAlgorithmOptions = new BeeSwarmAlgorithmOptionsType + { + EliteCount = 2, + Seed = 1, + CrossOver = 0.3, + Beta = 0.4, + Delta = 0.7, + DifferentialWeight = 0.3, + MaximumNonImprovingGenerations = 10, + PopulationCount = 200, + GenerationCount = 40 + }; + } + + private void TransferSoils(SoilList damSoilList, SoilType[] kernelSoils, FixedSoilStressType[] kernelFixedSoilStresses, ObjectRegistry registry) + { + if (damSoilList != null) + { + var i = 0; + foreach (Soil damSoil in damSoilList.Soils) + { + SoilType kernelSoil = CreateSoil(damSoil, registry); + kernelSoils[i] = kernelSoil; + var kernelFixedSoilStressType = new FixedSoilStressType(); + kernelFixedSoilStressType.POP = damSoil.PoP; + kernelFixedSoilStressType.Soil = kernelSoil.Key; + kernelFixedSoilStresses[i] = kernelFixedSoilStressType; + i++; + } + } + } + + private static SoilType CreateSoil(Soil soil, ObjectRegistry registry) + { + SoilType soilType = InterfaceConversionHelper.ConvertToMacroStabilitySoil(soil); + soilType.Key = registry.GetId(soil); + return soilType; + } + + private void TransferSoilProfile(SoilProfile2D damSoilProfile2D, SoilProfileType kernelSoilProfile, + PreconsolidationStressType[] preConsolidationStresses, ObjectRegistry registry) + { + // Add points + kernelSoilProfile.Geometry = new GeometryType + { + Bottom = damSoilProfile2D.Geometry.Bottom, + Left = damSoilProfile2D.Geometry.Left, + Right = damSoilProfile2D.Geometry.Right, + Points = new PointType[damSoilProfile2D.Geometry.Points.Count], + Curves = new CurveType[damSoilProfile2D.Geometry.Curves.Count], + Loops = new LoopType[damSoilProfile2D.Geometry.Loops.Count], + GeometrySurfaces = new GeometrySurfaceType[damSoilProfile2D.Geometry.Surfaces.Count] + }; + kernelSoilProfile.SoilSurfaces = new SoilSurfaceType[damSoilProfile2D.Surfaces.Count]; + + TransferSoilProfileGeometryPoints(damSoilProfile2D, kernelSoilProfile, registry); + TransferSoilProfileGeometryCurves(damSoilProfile2D, kernelSoilProfile, registry); + TransferSoilProfileGeometryLoops(damSoilProfile2D, kernelSoilProfile, registry); + TransferSoilProfileGeometrySurfaces(damSoilProfile2D, kernelSoilProfile, registry); + + TransferSoilProfileSoilLayers2D(damSoilProfile2D, kernelSoilProfile, registry); + + TransferSoilProfilePreConsolidationStresses(damSoilProfile2D, preConsolidationStresses); + } + + private static void TransferSoilProfilePreConsolidationStresses(SoilProfile2D damSoilProfile2D, PreconsolidationStressType[] preConsolidationStresses) + { + var i = 0; + foreach (PreConsolidationStress preConsolidationStress in damSoilProfile2D.PreconsolidationStresses) + { + var kernelPreConsolidationStressType = new PreconsolidationStressType + { + Point = new Point2DType + { + X = preConsolidationStress.X, + Z = preConsolidationStress.Z + }, + StressValue = preConsolidationStress.StressValue + }; + preConsolidationStresses[i] = kernelPreConsolidationStressType; + i++; + } + } + + private static void TransferSoilProfileSoilLayers2D(SoilProfile2D damSoilProfile2D, SoilProfileType kernelSoilProfile, ObjectRegistry registry) + { + var i = 0; + foreach (SoilLayer2D damSoilLayer2D in damSoilProfile2D.Surfaces) + { + var kernelSoilLayer2D = new SoilSurfaceType + { + Key = registry.GetId(damSoilLayer2D), + Name = damSoilLayer2D.Name, + IsAquifer = damSoilLayer2D.IsAquifer, + GeometrySurface = registry.GetId(damSoilLayer2D.GeometrySurface), + Soil = registry.GetId(damSoilLayer2D.Soil), + WaterPressureInterpolationModelSpecified = true, + WaterPressureInterpolationModel = InterfaceConversionHelper.ConvertToMacroStabilityWaterPressureInterpolationModel(damSoilLayer2D + .WaterpressureInterpolationModel) + }; + kernelSoilProfile.SoilSurfaces[i] = kernelSoilLayer2D; + i++; + } + } + + private static void TransferSoilProfileGeometrySurfaces(SoilProfile2D damSoilProfile2D, SoilProfileType kernelSoilProfile, ObjectRegistry registry) + { + int i; + i = 0; + foreach (SoilLayer2D damSurface in damSoilProfile2D.Surfaces) + { + var kernelGeometrySurface = new GeometrySurfaceType + { + Key = registry.GetId(damSurface) + }; + GeometrySurface damGeometrySurface = damSurface.GeometrySurface; + kernelGeometrySurface.OuterLoop = registry.GetId(damGeometrySurface.OuterLoop); + kernelGeometrySurface.InnerLoops = new GeometrySurfaceTypeInnerLoop[damGeometrySurface.InnerLoops.Count]; + var j = 0; + foreach (GeometryLoop damSurfaceInnerLoop in damGeometrySurface.InnerLoops) + { + kernelGeometrySurface.InnerLoops[j] = new GeometrySurfaceTypeInnerLoop + { + Loop = registry.GetId(damSurfaceInnerLoop) + }; + } + + kernelSoilProfile.Geometry.GeometrySurfaces[i] = kernelGeometrySurface; + } + } + + private static void TransferSoilProfileGeometryLoops(SoilProfile2D damSoilProfile2D, SoilProfileType kernelSoilProfile, ObjectRegistry registry) + { + var i = 0; + foreach (GeometryLoop damLoop in damSoilProfile2D.Geometry.Loops) + { + var kernelLoop = new LoopType + { + Key = registry.GetId(damLoop), + Curves = new LoopTypeCurve[damLoop.CurveList.Count] + }; + var j = 0; + foreach (GeometryCurve geometryCurve in damLoop.CurveList) + { + var kernelCurve = new LoopTypeCurve + { + Curve = registry.GetId(geometryCurve) + }; + kernelLoop.Curves[j] = kernelCurve; + j++; + } + + kernelSoilProfile.Geometry.Loops[i] = kernelLoop; + i++; + } + } + + private static void TransferSoilProfileGeometryCurves(SoilProfile2D damSoilProfile2D, SoilProfileType kernelSoilProfile, ObjectRegistry registry) + { + var i = 0; + foreach (GeometryCurve damCurve in damSoilProfile2D.Geometry.Curves) + { + var kernelCurve = new CurveType + { + HeadPoint = registry.GetId(damCurve.HeadPoint), + EndPoint = registry.GetId(damCurve.EndPoint), + Key = registry.GetId(damCurve) + }; + kernelSoilProfile.Geometry.Curves[i] = kernelCurve; + i++; + } + } + + private static void TransferSoilProfileGeometryPoints(SoilProfile2D damSoilProfile2D, SoilProfileType kernelSoilProfile, ObjectRegistry registry) + { + var i = 0; + foreach (Point2D damPoint in damSoilProfile2D.Geometry.Points) + { + var kernelPoint = new PointType + { + X = damPoint.X, + Z = damPoint.Z, + Key = registry.GetId(damPoint) + }; + kernelSoilProfile.Geometry.Points[i] = kernelPoint; + i++; + } + } +} \ No newline at end of file Index: DamEngine/trunk/src/build/Base.targets =================================================================== diff -u -r5317 -r6366 --- DamEngine/trunk/src/build/Base.targets (.../Base.targets) (revision 5317) +++ DamEngine/trunk/src/build/Base.targets (.../Base.targets) (revision 6366) @@ -6,6 +6,7 @@ net6.0-windows latest Deltares + DAM Engine Copyright © Deltares $([System.DateTime]::Today.ToString(yyyy)) 0 24.1.0