Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityOutwards/MacroStabilityOutwardsKernelWrapper.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityOutwards/MacroStabilityOutwardsKernelWrapper.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityOutwards/MacroStabilityOutwardsKernelWrapper.cs (revision 3800) @@ -0,0 +1,353 @@ +// Copyright (C) Stichting Deltares 2022. 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.Data; +using System.IO; +using Deltares.DamEngine.Calculators.DikesDesign; +using Deltares.DamEngine.Calculators.KernelWrappers.Common; +using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces; +using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon; +using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon.MacroStabilityIo; +using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards; +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.Standard.Calculation; +using Deltares.DamEngine.Data.Standard.Logging; +using Deltares.MacroStability.CSharpWrapper; +using Deltares.MacroStability.CSharpWrapper.Input; +using Deltares.MacroStability.CSharpWrapper.Output; +using CharacteristicPointType = Deltares.DamEngine.Data.Geotechnics.CharacteristicPointType; +using MacroStabilityOutput = Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards.MacroStabilityOutput; + +namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityOutwards +{ + /// + /// Class for the wrapper around the Stability Outwards calculator + /// + /// + public class MacroStabilityOutwardsKernelWrapper : IKernelWrapper + { + private Calculator stabilityCalculator; + private string fileNameForCalculation; + + /// + /// Gets or sets the failure mechanisme paramaters for mstab. + /// + /// + /// The failure mechanisme paramaters mstab. + /// + public FailureMechanismParametersMStab FailureMechanismParametersMStab { get; set; } + + /// + /// Prepares the specified dam kernel input. + /// + /// The dam kernel input. + /// + /// The kernel data input. + /// The kernel data output + /// + /// Result of the prepare + /// + public PrepareResult Prepare(DamKernelInput damKernelInput, int iterationIndex, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput) + { + fileNameForCalculation = ""; + var macroStabilityInput = new MacroStabilityKernelDataInput(); + kernelDataInput = macroStabilityInput; + var macroStabilityOutput = new MacroStabilityOutput + { + CalculationResult = CalculationResult.NoRun + }; + kernelDataOutput = macroStabilityOutput; + if (damKernelInput.SubSoilScenario.SegmentFailureMechanismType != null && + damKernelInput.SubSoilScenario.SegmentFailureMechanismType.Value == SegmentFailureMechanismType.Stability) + { + try + { + if (FailureMechanismParametersMStab.MStabParameters.Model != MStabModelType.Bishop) + { + throw new NotImplementedException(); + } + + MacroStabilityCommonHelper.EnsureSoilProfile2DIsFilled(damKernelInput.SubSoilScenario, damKernelInput.Location.SurfaceLine, + damKernelInput.Location.GetDikeEmbankmentSoil()); + + const bool useRiverLevelLow = false; + //Determine pl Lines. + var plLines = UpliftHelper.DeterminePlLinesForStability(damKernelInput, useRiverLevelLow, out _); + + var fillMacroStabilityWrapperFromEngine = new FillMacroStabilityWrapperInputFromEngine + { + TrafficLoad = MacroStabilityCommonHelper.FillTrafficLoad(damKernelInput) + }; + FailureMechanismParametersMStab.MStabParameters.GridPosition = MStabGridPosition.Left; + damKernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab + .MStabParameters.GridPosition = MStabGridPosition.Left; + fillMacroStabilityWrapperFromEngine.BishopCalculationGrid = MacroStabilityCommonHelper.FillBishopCalculationGrid(damKernelInput); + + var left = damKernelInput.Location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside).X; + var right = damKernelInput.Location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X; + var penetrationLength = damKernelInput.Location.ModelParametersForPlLines.PenetrationLength; + var soilProfile1D = damKernelInput.SubSoilScenario.SoilProfile2D.GetSoilProfile1D( + damKernelInput.Location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X); + var waterNet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile1D, penetrationLength, left, right); + + macroStabilityInput.Input = fillMacroStabilityWrapperFromEngine.CreateMacroStabilityInput(damKernelInput, FailureMechanismParametersMStab.MStabParameters, waterNet); + fileNameForCalculation = MacroStabilityCommonHelper.GetStabilityInputFileName(damKernelInput, iterationIndex, FailureMechanismParametersMStab.MStabParameters.Model); + stabilityCalculator = new Calculator(macroStabilityInput.Input); + var firstPrepareResult = PrepareKernel(stabilityCalculator, fileNameForCalculation); + + return firstPrepareResult; + } + catch (Exception e) + { + macroStabilityOutput.Message = new LogMessage { MessageType = LogMessageType.FatalError, Message = e.Message }; + kernelDataOutput = macroStabilityOutput; + return PrepareResult.Failed; + } + } + kernelDataInput = null; + return PrepareResult.NotRelevant; + } + + private PrepareResult PrepareKernel(Calculator calculator, string fileName) + { + try + { + // For now a simple check to see if any data has been past at all. + var inputAsXml = calculator.KernelInputXml; + + File.WriteAllText(fileName, inputAsXml); + + if (inputAsXml.Length > 10) + { + return PrepareResult.Successful; + } + + return PrepareResult.Failed; + } + catch + { + return PrepareResult.Failed; + } + } + + /// + /// Validates the specified kernel data input. + /// + /// The kernel data input. + /// The kernel data output. + /// The return messages. + /// + /// Zero when there are no errors, one when there are errors that prevent a calculation + /// + public int Validate(IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, out List messages) + { + MacroStabilityKernelDataInput macroStabilityKernelDataInput = (MacroStabilityKernelDataInput)kernelDataInput; + messages = new List(); + try + { + var result = new Validator(macroStabilityKernelDataInput.Input).Validate(); + if (result.IsValid) + { + return 0; + } + + if (kernelDataOutput != null) + { + ((MacroStabilityOutput)kernelDataOutput).CalculationResult = CalculationResult.InvalidInputData; + } + + foreach (var resultMessage in result.Messages) + { + var message = new LogMessage + { + Message = resultMessage.Content + }; + switch (resultMessage.MessageType) + { + case MessageType.Error: + { + message.MessageType = LogMessageType.Error; + break; + } + case MessageType.Info: + { + message.MessageType = LogMessageType.Info; + break; + } + case MessageType.Warning: + { + message.MessageType = LogMessageType.Warning; + break; + } + } + + messages.Add(message); + } + + return 1; + } + catch (Exception e) + { + var message = new LogMessage { MessageType = LogMessageType.FatalError, Message = e.Message }; + messages.Add(message); + if (kernelDataOutput != null) + { + ((MacroStabilityOutput)kernelDataOutput).CalculationResult = CalculationResult.InvalidInputData; + } + + return 1; + } + } + + /// + /// Executes the kernel. + /// + /// The kernel data input. + /// The kernel data output. + /// The return messages. + public void Execute(IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, out List messages) + { + MacroStabilityKernelDataInput macroStabilityKernelDataInput = (MacroStabilityKernelDataInput)kernelDataInput; + MacroStabilityOutput macroStabilityOutput = (MacroStabilityOutput)kernelDataOutput; + MacroStabilityCommonHelper.ThrowWhenMacroStabilityKernelInputNull(macroStabilityKernelDataInput); + MacroStabilityCommonHelper.ThrowWhenMacroStabilityKernelOutputNull(macroStabilityOutput); + + PerformStabilityCalculation(macroStabilityKernelDataInput.Input, macroStabilityOutput, + fileNameForCalculation, stabilityCalculator, out messages); + var fileName = Path.GetFileNameWithoutExtension(fileNameForCalculation); + foreach (var logMessage in messages) + { + logMessage.Message = fileName + ": " + logMessage.Message; + } + } + + private void PerformStabilityCalculation(MacroStabilityInput input, MacroStabilityOutput macroStabilityOutput, + string fileName, ICalculator calculator, out List messages) + { + macroStabilityOutput.CalculationResult = CalculationResult.NoRun; + macroStabilityOutput.StabilityOutputItems = new List(); + messages = new List(); + try + { + var macroStabilityOutputKernel = calculator.Calculate(); + FillEngineFromMacroStabilityWrapperOutput.FillEngineDataWithResults(macroStabilityOutputKernel, macroStabilityOutput, + out messages); +#if DEBUG + foreach (var stabilityOutputItem in macroStabilityOutput.StabilityOutputItems) + { + input.StabilityModel.BishopCalculationCircle = stabilityOutputItem.BishopCalculationCircle; + MacroStabilityCommonHelper.WriteStixFileBasedOnInputAndResultsSearchGrid(fileName, input); + } +#endif + MacroStabilityCommonHelper.WriteStixFileBasedOnInputAndResultsSlipPlane(fileName, input, macroStabilityOutput); + } + catch (Exception e) + { + macroStabilityOutput.CalculationResult = CalculationResult.UnexpectedError; + messages.Add(new LogMessage(LogMessageType.Error, null, e.Message)); + } + } + + /// + /// Fills the design results with the kernel output. + /// + /// The dam kernel input. + /// The kernel data output. + /// + /// The result message. + /// The design results. + /// + public void PostProcess(DamKernelInput damKernelInput, IKernelDataOutput kernelDataOutput, DesignScenario designScenario, + string resultMessage, out List designResults) + { + MacroStabilityCommonHelper.ThrowWhenMacroStabilityDamKernelInputNull(damKernelInput); + var macroStabilityOutput = kernelDataOutput as MacroStabilityOutput; + MacroStabilityCommonHelper.ThrowWhenMacroStabilityKernelOutputNull(macroStabilityOutput); + designResults = new List(); + if (macroStabilityOutput?.StabilityOutputItems != null && macroStabilityOutput.StabilityOutputItems.Count > 0) + { + var macroStabilityOutputItem = macroStabilityOutput.StabilityOutputItems[0]; + if (macroStabilityOutputItem != null) + { + var designResult = MacroStabilityCommonHelper.NewDesignResult(damKernelInput, designScenario); + MacroStabilityCommonHelper.FillDesignResult(macroStabilityOutputItem, designResult); + designResult.StabilityDesignResults.NumberOfIterations = 0; + designResult.StabilityDesignResults.UpliftSituation = macroStabilityOutput.UpliftSituation; + designResults.Add(designResult); + } + } + } + + /// + /// Calculates the design at point. + /// + /// The dam kernel input. + /// The kernel data input. + /// The kernel data output. + /// The point. + /// The messages. + /// + /// + public ShoulderDesign CalculateDesignAtPoint(DamKernelInput damKernelInput, IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, GeometryPoint point, out List messages) + { + throw new NotImplementedException(); + } + + /// + /// Evaluates the design (current factor greater than desired factor) + /// + /// The dam kernel input. + /// The kernel data input. + /// The kernel data output. + /// The design advise. + /// The evaluation message. + /// + /// if the design was succesful + /// + /// + public bool EvaluateDesign(DamKernelInput damKernelInput, IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, + out DesignAdvise designAdvise, out string evaluationMessage) + { + throw new NotImplementedException(); + } + + public void PrepareDesign(IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput, + int iterationIndex, out EmbankmentDesignParameters embankmentDesignParameters) + { + throw new NotImplementedException(); + } + + /// + /// Gets the design strategy + /// + /// + /// + public DesignStrategy GetDesignStrategy(DamKernelInput damKernelInput) + { + return DesignStrategy.NoDesignPossible; + } + } +} Index: DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/MacroStabilityOutwardsTests.cs =================================================================== diff -u -r3520 -r3800 --- DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/MacroStabilityOutwardsTests.cs (.../MacroStabilityOutwardsTests.cs) (revision 3520) +++ DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/MacroStabilityOutwardsTests.cs (.../MacroStabilityOutwardsTests.cs) (revision 3800) @@ -1,4 +1,4 @@ -// Copyright (C) Stichting Deltares 2021. All rights reserved. +// Copyright (C) Stichting Deltares 2022. All rights reserved. // // This file is part of the Dam Engine. // @@ -20,32 +20,22 @@ // All rights reserved. using System.IO; -using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Interface; using Deltares.DamEngine.Io; -using Deltares.DamEngine.TestHelpers; using NUnit.Framework; -using ConversionHelper = Deltares.DamEngine.Interface.ConversionHelper; namespace Deltares.DamEngine.IntegrationTests.IntegrationTests { [TestFixture] public class MacroStabilityOutwardsTests { - /// Test for different segmentFailureMechanismType - /// The soilprobabilities are set tot the specified segmentFailureMechanismType - [Test] - [Ignore("Test disabled due to removal of the old MacroStability kernel wrapper implementation")] - [TestCase(ConversionHelper.InputSegmentFailureMechanismStability)] - [TestCase(ConversionHelper.InputSegmentFailureMechanismAll)] - public void TestRunMacroStabilityTutorialDesignBishop(int segmentFailureMechanismType) + private const double Tolerance = 0.0005; + [Test] + [TestCase("InputFileForStabOutsideBishopAutomaticGrid.xml", 1.810)] + [TestCase("InputFileForStabOutsideBishopSpecifiedGrid.xml", 1.813)] + public void TestDoesBishopOutwardsProduceResults(string fileName, double factorOfSafety) { - // Based on ".data\DamEngineTestProjects\DAM Tutorial Design\DAM Tutorial Design.damx" - // Set Analysis type to "No adaption" - // Select first location (DWP_1) - // Set Calculation Options: Stability Inside - Bishop - // DO NOT SET: Set Calculation Options: Stability Outside - Bishop, this is done in the test itself - // Expected results are taken from test TestStabilityClassicOutsideWith2DstiFiles in FailureMechanismTests of DamUI. + // Expected results are taken as they came as calculated const string calcDir = "TestOutStabBishop"; if (Directory.Exists(calcDir)) { @@ -55,26 +45,17 @@ Directory.CreateDirectory(calcDir); - const string fileName = @"TestFiles\MacroStabilityTutorialDesignInputFile.xml"; - string inputString = File.ReadAllText(fileName); - inputString = XmlAdapter.ChangeValueInXml(inputString, "ProjectPath", ""); // Current directory will be used - inputString = XmlAdapter.ChangeValueInXml(inputString, "CalculationMap", calcDir); // Current directory will be used - inputString = XmlAdapter.ChangeValueInXml(inputString, "MapForSoilgeometries2D", @"TestFiles\DAM Tutorial Design.geometries2D.0\"); - inputString = XmlAdapter.ChangeValueInXml(inputString, "SoilDatabaseName", @"TestFiles\DAM Tutorial Design0.soilmaterials.mdb"); - inputString = XmlAdapter.ChangeValueInXml(inputString, "SegmentFailureMechanismType", segmentFailureMechanismType.ToString()); - File.WriteAllText(fileName + ".txt", inputString); + string fullFileName = @"TestFiles\" + fileName; + string inputString = File.ReadAllText(fullFileName); EngineInterface engineInterface = new EngineInterface(inputString); Assert.IsNotNull(engineInterface.DamProjectData); - engineInterface.DamProjectData.DamProjectCalculationSpecification.CurrentSpecification.StabilityModelType = MStabModelType.Bishop; - engineInterface.DamProjectData.DamProjectCalculationSpecification.CurrentSpecification.FailureMechanismParametersMStab.MStabParameters.GridPosition = MStabGridPosition.Left; - engineInterface.DamProjectData.DamProjectCalculationSpecification.CurrentSpecification.FailureMechanismSystemType = FailureMechanismSystemType.StabilityOutside; string outputString = engineInterface.Run(); Assert.IsNotNull(outputString); var output = DamXmlSerialization.LoadOutputFromXmlString(outputString); - Assert.IsNull(output.Results.CalculationResults, "Results available when not expected"); - Assert.AreEqual(1, output.Results.CalculationMessages.Length); - Assert.IsTrue(output.Results.CalculationMessages[0].Message1.Contains("should be higher than dike toe at river side")); + Assert.IsNotNull(output.Results.CalculationResults, "Results available when not expected"); + Assert.AreEqual(factorOfSafety, output.Results.CalculationResults[0].StabilityDesignResults.SafetyFactor, Tolerance); } + } } Index: DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/DesignCalculatorTests.cs =================================================================== diff -u -r3793 -r3800 --- DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/DesignCalculatorTests.cs (.../DesignCalculatorTests.cs) (revision 3793) +++ DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/DesignCalculatorTests.cs (.../DesignCalculatorTests.cs) (revision 3800) @@ -84,7 +84,8 @@ var output = DamXmlSerialization.LoadOutputFromXmlString(outputString); // As the data is not entirely correct for the new kernel, we expect 1 error. Assert.AreEqual(1, output.Results.CalculationMessages.Length); - Assert.IsTrue(output.Results.CalculationMessages[0].Message1.Contains("De berekening is mislukt met de volgende foutmelding"), output.Results.CalculationMessages[0].Message1); + Assert.IsTrue(output.Results.CalculationMessages[0].Message1.Contains( + "De berekening is mislukt met de volgende foutmelding"), output.Results.CalculationMessages[0].Message1); } [Test] Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/KernelWrapperHelper.cs =================================================================== diff -u -r3663 -r3800 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/KernelWrapperHelper.cs (.../KernelWrapperHelper.cs) (revision 3663) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/KernelWrapperHelper.cs (.../KernelWrapperHelper.cs) (revision 3800) @@ -25,6 +25,7 @@ using Deltares.DamEngine.Calculators.KernelWrappers.DamPipingSellmeijerVnk; using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces; using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards; +using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityOutwards; using Deltares.DamEngine.Calculators.KernelWrappers.WtiPipingSellmeijerRevised; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.Standard; @@ -47,6 +48,18 @@ IKernelWrapper kernelWrapper = null; switch (currentSpecification.FailureMechanismSystemType) { + case FailureMechanismSystemType.StabilityOutside: + switch (currentSpecification.StabilityModelType) + { + case MStabModelType.Bishop: + kernelWrapper = new MacroStabilityOutwardsKernelWrapper(); + var macroStabilityOutwardsKernelWrapper = (MacroStabilityOutwardsKernelWrapper)kernelWrapper; + macroStabilityOutwardsKernelWrapper.FailureMechanismParametersMStab = currentSpecification.FailureMechanismParametersMStab.Copy(); + break; + default: + throw new NotImplementedException(); + } + break; case FailureMechanismSystemType.StabilityInside: switch (currentSpecification.StabilityModelType) { Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj =================================================================== diff -u -r3690 -r3800 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 3690) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 3800) @@ -84,6 +84,7 @@ + @@ -98,6 +99,7 @@ + Index: DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/Deltares.DamEngine.IntegrationTests.csproj =================================================================== diff -u -r3666 -r3800 --- DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/Deltares.DamEngine.IntegrationTests.csproj (.../Deltares.DamEngine.IntegrationTests.csproj) (revision 3666) +++ DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/Deltares.DamEngine.IntegrationTests.csproj (.../Deltares.DamEngine.IntegrationTests.csproj) (revision 3800) @@ -91,6 +91,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + Always Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelper.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelper.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelper.cs (revision 3800) @@ -0,0 +1,338 @@ +// Copyright (C) Stichting Deltares 2022. 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.Data; +using System.IO; +using System.Text.RegularExpressions; +using Deltares.DamEngine.Calculators.KernelWrappers.Common; +using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards; +using Deltares.DamEngine.Calculators.Properties; +using Deltares.DamEngine.Data.Design; +using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.General.Results; +using Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.Data.Standard.Calculation; +using Deltares.MacroStability.CSharpWrapper.Input; +using Deltares.MacroStability.CSharpWrapper.Output; +using Deltares.StixFileWriter; +using CharacteristicPointType = Deltares.DamEngine.Data.Geotechnics.CharacteristicPointType; +using MacroStabilityOutput = Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards.MacroStabilityOutput; +using Soil = Deltares.DamEngine.Data.Geotechnics.Soil; + +namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon +{ + /// + /// Class with helper methods for the Macro Stability Wrappers. + /// + public static class MacroStabilityCommonHelper + { + /// + /// Ensures the soil profile2d is filled. + /// + /// The sub soil scenario. + /// The surface line2. + /// The dike embankment soil. + public static void EnsureSoilProfile2DIsFilled(SoilGeometryProbability subSoilScenario, SurfaceLine2 surfaceLine2, Soil dikeEmbankmentSoil) + { + var soilProfile2D = subSoilScenario.SoilProfile2D; + if (soilProfile2D == null) + { + var soilSurfaceProfile = new SoilSurfaceProfile + { + SoilProfile = subSoilScenario.SoilProfile1D, + SurfaceLine2 = surfaceLine2, + Name = subSoilScenario.SoilProfile1D.Name, + DikeEmbankmentMaterial = dikeEmbankmentSoil + }; + // Convert the soilSurfaceProfile to a SoilProfile2D to be able to edit it properly. + var soilProfile2DNew = soilSurfaceProfile.ConvertToSoilProfile2D(); + subSoilScenario.SoilProfile2D = soilProfile2DNew; + subSoilScenario.SoilProfile2DName = soilProfile2DNew.Name; + subSoilScenario.SoilProfileType = SoilProfileType.ProfileType2D; + subSoilScenario.SoilProfile1D = null; + } + } + + /// + /// Fills the traffic load. + /// + /// The dam kernel input. + /// + public static TrafficLoad FillTrafficLoad(DamKernelInput damKernelInput) + { + TrafficLoad trafficLoad = null; + if (damKernelInput.Location.StabilityOptions != null && damKernelInput.Location.StabilityOptions.TrafficLoad.HasValue && + !(Math.Abs(damKernelInput.Location.StabilityOptions.TrafficLoad.Value) < 1e-6)) + { + trafficLoad = new TrafficLoad + { + Pressure = damKernelInput.Location.StabilityOptions.TrafficLoad.Value, + XEnd = damKernelInput.Location.SurfaceLine + .CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadInside).X, + XStart = damKernelInput.Location.SurfaceLine + .CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadOutside).X + }; + } + return trafficLoad; + } + + /// + /// Fills the bishop calculation grid. + /// + /// The dam kernel input. + /// + public static BishopCalculationGrid FillBishopCalculationGrid(DamKernelInput damKernelInput) + { + var slipCircleDefinition = damKernelInput.DamFailureMechanismeCalculationSpecification + .FailureMechanismParametersMStab.MStabParameters.SlipCircleDefinition; + var minimumCircleDepth = damKernelInput.DamFailureMechanismeCalculationSpecification + .FailureMechanismParametersMStab.MStabParameters.CalculationOptions.MinimalCircleDepth; + var gridPosition = damKernelInput.DamFailureMechanismeCalculationSpecification + .FailureMechanismParametersMStab.MStabParameters.GridPosition; + var bishopCalculationGrid = BishopGridCreator.DetermineGridsFromSettings(gridPosition, + slipCircleDefinition, damKernelInput.Location.SurfaceLine); + var centerOfLeftGridXCoordinate = (bishopCalculationGrid.GridXLeft + bishopCalculationGrid.GridXRight) * 0.5; + var soilProfile1DAtCenterOfLeftGridXCoordinate = + damKernelInput.SubSoilScenario.DetermineSoilProfile1DAtX(centerOfLeftGridXCoordinate, damKernelInput.Location.SurfaceLine, + damKernelInput.Location.GetDikeEmbankmentSoil()); + BishopGridCreator.DetermineTangentLines(bishopCalculationGrid, slipCircleDefinition, + soilProfile1DAtCenterOfLeftGridXCoordinate, minimumCircleDepth); + + return bishopCalculationGrid; + } + + /// + /// Gets the name of the stability input file. + /// + /// The dam kernel input. + /// Index of the iteration. + /// The model. + /// + public static string GetStabilityInputFileName(DamKernelInput damKernelInput, int iterationIndex, MStabModelType model) + { + // Assume 2D sti-file, then check on type being 1D + string soilGeometryName = damKernelInput.SubSoilScenario.SoilProfile2DName; + string calculationName = DetermineCalculationFilename(damKernelInput.FilenamePrefix, soilGeometryName, iterationIndex); + const string filenameExtension = ".skx"; + string fileName = calculationName + filenameExtension; + string stabilityDirectory = GetStabilityCalculationDirectory(model, damKernelInput.CalculationDir); + return Path.Combine(stabilityDirectory, fileName); + } + + /// + /// Determines the calculation filename. + /// + /// The filename prefix. + /// Name of the soil geometry. + /// Index of the iteration. + /// + private static string DetermineCalculationFilename(string filenamePrefix, string soilGeometryName, int iterationIndex) + { + string calculationName; + if (iterationIndex <= 0) + { + calculationName = $"{filenamePrefix}_Pro({soilGeometryName})"; + } + else + { + calculationName = $"{filenamePrefix}_Pro({soilGeometryName})_Ite({iterationIndex})"; + } + return Regex.Replace(calculationName, @"[\\\/:\*\?""'<>|.]", "_"); + } + + /// + /// Gets the stability calculation directory. + /// + /// The model. + /// The project working path. + /// + private static string GetStabilityCalculationDirectory(MStabModelType model, string projectWorkingPath) + { + string calculationBaseDirectory = projectWorkingPath; + var stabilitySubDir = GetCalculationSubDir(model); + string stabilityDirectory = Path.Combine(calculationBaseDirectory, stabilitySubDir); + if (!Directory.Exists(stabilityDirectory)) + Directory.CreateDirectory(stabilityDirectory); + return stabilityDirectory; + } + + /// + /// Gets the calculation sub dir. + /// + /// The model. + /// + private static string GetCalculationSubDir(MStabModelType model) + { + const string stabilitySubDir = @"Stability\"; + var modelSubDirectory = model.ToString(); + var dir = Path.Combine(stabilitySubDir, modelSubDirectory); + return dir; + } + + /// + /// Throws the when macro stability kernel input is not assigned. + /// + /// The dam macro stability input. + /// + public static void ThrowWhenMacroStabilityKernelInputNull(MacroStabilityKernelDataInput macroStabilityKernelDataInput) + { + if (macroStabilityKernelDataInput == null) + { + throw new NoNullAllowedException(Resources.MacroStabilityKernelWrapper_NoMacroStabilityInputObjectDefined); + } + } + + /// + /// Throws the when macro stability kernel output is not assigned. + /// + /// The dam macro stability output. + /// + public static void ThrowWhenMacroStabilityKernelOutputNull(MacroStabilityOutput macroStabilityOutput) + { + if (macroStabilityOutput == null) + { + throw new NoNullAllowedException(Resources.MacroStabilityKernelWrapper_NoMacroStabilityOutputObjectDefined); + } + } + + /// + /// Throws the when macro stability dam kernel input is not assigned. + /// + /// The dam kernel input. + /// + public static void ThrowWhenMacroStabilityDamKernelInputNull(DamKernelInput damKernelInput) + { + if (damKernelInput == null) + { + throw new NoNullAllowedException(Resources.MacroStabilityKernelWrapper_NoDamInputObjectDefinedForMacroStability); + } + } + + /// + /// Writes the stix file based on input and results search grid. + /// + /// Name of the file. + /// The input. + public static void WriteStixFileBasedOnInputAndResultsSearchGrid(string fileName, MacroStabilityInput input) + { + if (!(input.StabilityModel.ModelOption == StabilityModelOptionType.UpliftVan && + input.StabilityModel.SearchAlgorithm == SearchAlgorithm.Beeswarm)) + { + var fileNameForCalculationAsStix = DetermineStixFilename(fileName, "input"); + var inputStixFile = new StixWriter(); + inputStixFile.FillInfo("DAM Engine", Path.GetDirectoryName(fileName), + Path.GetFileName(fileName), true); + StixFileWrite(inputStixFile, fileNameForCalculationAsStix, input); + } + } + + /// + /// Writes the stix file based on input and results slip plane. + /// + /// Name of the file. + /// The input. + /// The macro stability output. + public static void WriteStixFileBasedOnInputAndResultsSlipPlane(string fileName, MacroStabilityInput input, + MacroStabilityOutput macroStabilityOutput) + { + if (macroStabilityOutput.CalculationResult == CalculationResult.Succeeded) + { + foreach (var macroStabilityOutputItem in macroStabilityOutput.StabilityOutputItems) + { + macroStabilityOutputItem.CalculationPath = Path.GetDirectoryName(fileName); + macroStabilityOutputItem.ProjectName = Path.GetFileName(fileName); + var fileNameForCalculationAsStix = DetermineStixFilename(fileName, "result"); + var resultStixWrite = new StixWriter(); + resultStixWrite.FillInfo("DAM Engine", macroStabilityOutputItem.CalculationPath, + macroStabilityOutputItem.ProjectName, true); + resultStixWrite.FillCalculatedCircle(macroStabilityOutputItem.ActiveCenterPoint.X, + macroStabilityOutputItem.ActiveCenterPoint.Z, + macroStabilityOutputItem.ActiveCenterPointRadius); + StixFileWrite(resultStixWrite, fileNameForCalculationAsStix, input); + } + } + } + + private static void StixFileWrite(StixWriter stixWriter, string fileName, MacroStabilityInput input) + { + if (File.Exists(fileName)) + { + File.Delete(fileName); + } + + stixWriter.WriteStixFile(fileName, input); + } + + private static string DetermineStixFilename(string fileNameForCalc, string suffix, string extension = ".stix") + { + return Path.Combine(Path.GetDirectoryName(fileNameForCalc) ?? string.Empty, + $"{Path.GetFileNameWithoutExtension(fileNameForCalc)}_{suffix}{extension}"); + } + + /// + /// Creates new designresult. + /// + /// The dam kernel input. + /// The design scenario. + /// + public static DesignResult NewDesignResult(DamKernelInput damKernelInput, DesignScenario designScenario) + { + string soilProfile2DName = damKernelInput.SubSoilScenario.ToString(); + var designResult = new DesignResult(damKernelInput.DamFailureMechanismeCalculationSpecification, + designScenario, damKernelInput.SubSoilScenario.SoilProfile1D, soilProfile2DName) + { + // initialize as failed + CalculationResult = CalculationResult.RunFailed, + StabilityDesignResults = new StabilityDesignResults() + }; + var stabilityDesignResults = new StabilityDesignResults + { + RedesignedSurfaceLine = damKernelInput.Location.SurfaceLine + }; + designResult.ProfileName = soilProfile2DName; + designResult.StabilityDesignResults = stabilityDesignResults; + designResult.CalculationSubDir = damKernelInput.CalculationDir; + return designResult; + } + + /// + /// Fills the design result. + /// + /// The macro stability output item. + /// The design result. + public static void FillDesignResult(MacroStabilityOutputItem macroStabilityOutputItem, DesignResult designResult) + { + designResult.BaseFileName = Path.GetFileNameWithoutExtension(macroStabilityOutputItem.ProjectName); + designResult.CalculationSubDir = macroStabilityOutputItem.CalculationPath; + designResult.CalculationResult = macroStabilityOutputItem.CalculationResult; + designResult.StabilityDesignResults.StabilityModelType = macroStabilityOutputItem.StabilityModelType; + if (designResult.CalculationResult == CalculationResult.Succeeded) + { + designResult.StabilityDesignResults.SafetyFactor = macroStabilityOutputItem.SafetyFactor; + } + designResult.StabilityDesignResults.ActiveCenterPoint = + macroStabilityOutputItem.ActiveCenterPoint; + designResult.StabilityDesignResults.ActiveCenterPointRadius = + macroStabilityOutputItem.ActiveCenterPointRadius; + designResult.StabilityDesignResults.ResultSlices = macroStabilityOutputItem.ResultSlices; + } + } +} Index: DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/TestFiles/InputFileForStabOutsideBishopSpecifiedGrid.xml =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/TestFiles/InputFileForStabOutsideBishopSpecifiedGrid.xml (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/TestFiles/InputFileForStabOutsideBishopSpecifiedGrid.xml (revision 3800) @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityInwards/MacroStabilityInwardsKernelWrapper.cs =================================================================== diff -u -r3790 -r3800 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityInwards/MacroStabilityInwardsKernelWrapper.cs (.../MacroStabilityInwardsKernelWrapper.cs) (revision 3790) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityInwards/MacroStabilityInwardsKernelWrapper.cs (.../MacroStabilityInwardsKernelWrapper.cs) (revision 3800) @@ -1,4 +1,4 @@ -// Copyright (C) Stichting Deltares 2021. All rights reserved. +// Copyright (C) Stichting Deltares 2022. All rights reserved. // // This file is part of the Dam Engine. // @@ -23,7 +23,6 @@ using System.Collections.Generic; using System.Data; using System.IO; -using System.Text.RegularExpressions; using Deltares.DamEngine.Calculators.DikesDesign; using Deltares.DamEngine.Calculators.KernelWrappers.Common; using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces; @@ -38,12 +37,10 @@ using Deltares.MacroStability.CSharpWrapper; using Deltares.MacroStability.CSharpWrapper.Input; using Deltares.MacroStability.CSharpWrapper.Output; -using Deltares.StixFileWriter; using CharacteristicPointType = Deltares.DamEngine.Data.Geotechnics.CharacteristicPointType; using GeometryPoint = Deltares.DamEngine.Data.Geometry.GeometryPoint; using LogMessage = Deltares.DamEngine.Data.Standard.Logging.LogMessage; using LogMessageType = Deltares.DamEngine.Data.Standard.Logging.LogMessageType; -using Soil = Deltares.DamEngine.Data.Geotechnics.Soil; namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards { @@ -97,7 +94,8 @@ model = MStabModelType.Bishop; } - EnsureSoilProfile2DIsFilled(damKernelInput.SubSoilScenario, damKernelInput.Location.SurfaceLine, damKernelInput.Location.GetDikeEmbankmentSoil()); + MacroStabilityCommonHelper.EnsureSoilProfile2DIsFilled(damKernelInput.SubSoilScenario, damKernelInput.Location.SurfaceLine, + damKernelInput.Location.GetDikeEmbankmentSoil()); const bool useRiverLevelLow = false; // Determine whether there is uplift @@ -106,14 +104,14 @@ var fillMacroStabilityWrapperFromEngine = new FillMacroStabilityWrapperInputFromEngine { - TrafficLoad = FillTrafficLoad(damKernelInput) + TrafficLoad = MacroStabilityCommonHelper.FillTrafficLoad(damKernelInput) }; if (FailureMechanismParametersMStab.MStabParameters.Model == MStabModelType.Bishop || FailureMechanismParametersMStab.MStabParameters.Model == MStabModelType.BishopUpliftVan) { - fillMacroStabilityWrapperFromEngine.BishopCalculationGrid = FillBishopCalculationGrid(damKernelInput); + fillMacroStabilityWrapperFromEngine.BishopCalculationGrid = MacroStabilityCommonHelper.FillBishopCalculationGrid(damKernelInput); } if (FailureMechanismParametersMStab.MStabParameters.Model == MStabModelType.UpliftVan || @@ -138,7 +136,7 @@ var waterNet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile1D, penetrationLength, left, right); macroStabilityInput.Input = fillMacroStabilityWrapperFromEngine.CreateMacroStabilityInput(damKernelInput, FailureMechanismParametersMStab.MStabParameters, waterNet); - fileNameForCalculation = GetStabilityInputFileName(damKernelInput, iterationIndex, FailureMechanismParametersMStab.MStabParameters.Model); + fileNameForCalculation = MacroStabilityCommonHelper.GetStabilityInputFileName(damKernelInput, iterationIndex, FailureMechanismParametersMStab.MStabParameters.Model); stabilityCalculator = new Calculator(macroStabilityInput.Input); var firstPrepareResult = PrepareKernel(stabilityCalculator, fileNameForCalculation); @@ -147,7 +145,7 @@ model = MStabModelType.UpliftVan; FailureMechanismParametersMStab.MStabParameters.Model = model; macroStabilityInput.Input = fillMacroStabilityWrapperFromEngine.CreateMacroStabilityInput(damKernelInput, FailureMechanismParametersMStab.MStabParameters, waterNet); - fileNameForSecondCalculation = GetStabilityInputFileName(damKernelInput, iterationIndex, FailureMechanismParametersMStab.MStabParameters.Model); + fileNameForSecondCalculation = MacroStabilityCommonHelper.GetStabilityInputFileName(damKernelInput, iterationIndex, FailureMechanismParametersMStab.MStabParameters.Model); // reset model FailureMechanismParametersMStab.MStabParameters.Model = MStabModelType.BishopUpliftVan; @@ -175,27 +173,6 @@ return PrepareResult.NotRelevant; } - private void EnsureSoilProfile2DIsFilled(SoilGeometryProbability subSoilScenario, SurfaceLine2 surfaceLine2, Soil dikeEmbankmentSoil) - { - var soilProfile2D = subSoilScenario.SoilProfile2D; - if (soilProfile2D == null) - { - var soilSurfaceProfile = new SoilSurfaceProfile - { - SoilProfile = subSoilScenario.SoilProfile1D, - SurfaceLine2 = surfaceLine2, - Name = subSoilScenario.SoilProfile1D.Name, - DikeEmbankmentMaterial = dikeEmbankmentSoil - }; - // Convert the soilSurfaceProfile to a SoilProfile2D to be able to edit it properly. - var soilProfile2DNew = soilSurfaceProfile.ConvertToSoilProfile2D(); - subSoilScenario.SoilProfile2D = soilProfile2DNew; - subSoilScenario.SoilProfile2DName = soilProfile2DNew.Name; - subSoilScenario.SoilProfileType = SoilProfileType.ProfileType2D; - subSoilScenario.SoilProfile1D = null; - } - } - private PrepareResult PrepareKernel(Calculator calculator, string fileName) { try @@ -218,24 +195,6 @@ } } - private BishopCalculationGrid FillBishopCalculationGrid(DamKernelInput damKernelInput) - { - var slipCircleDefinition = damKernelInput.DamFailureMechanismeCalculationSpecification - .FailureMechanismParametersMStab.MStabParameters.SlipCircleDefinition; - var minimumCircleDepth = damKernelInput.DamFailureMechanismeCalculationSpecification - .FailureMechanismParametersMStab.MStabParameters.CalculationOptions.MinimalCircleDepth; - var bishopCalculationGrid = BishopGridCreator.DetermineGridsFromSettings( - slipCircleDefinition, damKernelInput.Location.SurfaceLine); - var centerOfLeftGridXCoordinate = (bishopCalculationGrid.GridXLeft + bishopCalculationGrid.GridXRight) * 0.5; - var soilProfile1DAtCenterOfLeftGridXCoordinate = - damKernelInput.SubSoilScenario.DetermineSoilProfile1DAtX(centerOfLeftGridXCoordinate, damKernelInput.Location.SurfaceLine, - damKernelInput.Location.GetDikeEmbankmentSoil()); - BishopGridCreator.DetermineTangentLines(bishopCalculationGrid, slipCircleDefinition, - soilProfile1DAtCenterOfLeftGridXCoordinate, minimumCircleDepth); - - return bishopCalculationGrid; - } - private MacroStabilityCommon.UpliftVanCalculationGrid FillUpliftVanCalculationGrid(DamKernelInput damKernelInput) { var slipCircleDefinition = damKernelInput.DamFailureMechanismeCalculationSpecification @@ -256,24 +215,6 @@ return upliftVanCalculationGrid; } - private TrafficLoad FillTrafficLoad(DamKernelInput damKernelInput) - { - TrafficLoad trafficLoad = null; - if (damKernelInput.Location.StabilityOptions != null && damKernelInput.Location.StabilityOptions.TrafficLoad.HasValue && - !(Math.Abs(damKernelInput.Location.StabilityOptions.TrafficLoad.Value) < 1e-6)) - { - trafficLoad = new TrafficLoad - { - Pressure = damKernelInput.Location.StabilityOptions.TrafficLoad.Value, - XEnd = damKernelInput.Location.SurfaceLine - .CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadInside).X, - XStart = damKernelInput.Location.SurfaceLine - .CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadOutside).X - }; - } - return trafficLoad; - } - /// /// Validates the specified kernel data input. /// @@ -353,8 +294,8 @@ { MacroStabilityKernelDataInput macroStabilityKernelDataInput = (MacroStabilityKernelDataInput)kernelDataInput; MacroStabilityOutput macroStabilityOutput = (MacroStabilityOutput)kernelDataOutput; - ThrowWhenMacroStabilityKernelInputNull(macroStabilityKernelDataInput); - ThrowWhenMacroStabilityKernelOutputNull(macroStabilityOutput); + MacroStabilityCommonHelper.ThrowWhenMacroStabilityKernelInputNull(macroStabilityKernelDataInput); + MacroStabilityCommonHelper.ThrowWhenMacroStabilityKernelOutputNull(macroStabilityOutput); var isBishopUpliftVan = FailureMechanismParametersMStab.MStabParameters.Model == MStabModelType.BishopUpliftVan; if (isBishopUpliftVan) @@ -407,10 +348,10 @@ break; } - WriteStixFileBasedOnInputAndResultsSearchGrid(fileName, input); + MacroStabilityCommonHelper.WriteStixFileBasedOnInputAndResultsSearchGrid(fileName, input); } #endif - WriteStixFileBasedOnInputAndResultsSlipPlane(fileName, input, macroStabilityOutput); + MacroStabilityCommonHelper.WriteStixFileBasedOnInputAndResultsSlipPlane(fileName, input, macroStabilityOutput); } catch (Exception e) { @@ -419,69 +360,6 @@ } } - private void WriteStixFileBasedOnInputAndResultsSearchGrid(string fileName, MacroStabilityInput input) - { - if (!(input.StabilityModel.ModelOption == StabilityModelOptionType.UpliftVan && - input.StabilityModel.SearchAlgorithm == SearchAlgorithm.Beeswarm)) - { - var fileNameForCalculationAsStix = DetermineStixFilename(fileName, "input"); - var inputStixFile = new StixWriter(); - inputStixFile.FillInfo("DAM Engine", Path.GetDirectoryName(fileName), - Path.GetFileName(fileName), true); - StixFileWrite(inputStixFile, fileNameForCalculationAsStix, input); - } - } - - private void WriteStixFileBasedOnInputAndResultsSlipPlane(string fileName, MacroStabilityInput input, - MacroStabilityOutput macroStabilityOutput) - { - if (macroStabilityOutput.CalculationResult == CalculationResult.Succeeded) - { - foreach (var macroStabilityOutputItem in macroStabilityOutput.StabilityOutputItems) - { - macroStabilityOutputItem.CalculationPath = Path.GetDirectoryName(fileName); - macroStabilityOutputItem.ProjectName = Path.GetFileName(fileName); - var fileNameForCalculationAsStix = DetermineStixFilename(fileName, "result"); - var resultStixWrite = new StixWriter(); - resultStixWrite.FillInfo("DAM Engine", macroStabilityOutputItem.CalculationPath, - macroStabilityOutputItem.ProjectName, true); - switch (macroStabilityOutputItem.StabilityModelType) - { - case MStabModelType.Bishop: - resultStixWrite.FillCalculatedCircle(macroStabilityOutputItem.ActiveCenterPoint.X, - macroStabilityOutputItem.ActiveCenterPoint.Z, - macroStabilityOutputItem.ActiveCenterPointRadius); - break; - case MStabModelType.UpliftVan: - resultStixWrite.FillCalculatedDualCircle(macroStabilityOutputItem.ActiveCenterPoint.X, - macroStabilityOutputItem.ActiveCenterPoint.Z, - macroStabilityOutputItem.ActiveCenterPointRadius, - macroStabilityOutputItem.PassiveCenterPoint.X, - macroStabilityOutputItem.PassiveCenterPoint.Z); - break; - } - - StixFileWrite(resultStixWrite, fileNameForCalculationAsStix, input); - } - } - } - - private void StixFileWrite(StixWriter stixWriter, string fileName, MacroStabilityInput input) - { - if (File.Exists(fileName)) - { - File.Delete(fileName); - } - - stixWriter.WriteStixFile(fileName, input); - } - - private string DetermineStixFilename(string fileNameForCalc, string suffix, string extension = ".stix") - { - return Path.Combine(Path.GetDirectoryName(fileNameForCalc) ?? string.Empty, - $"{Path.GetFileNameWithoutExtension(fileNameForCalc)}_{suffix}{extension}"); - } - /// /// Fills the design results with the kernel output. /// @@ -494,17 +372,17 @@ public void PostProcess(DamKernelInput damKernelInput, IKernelDataOutput kernelDataOutput, DesignScenario designScenario, string resultMessage, out List designResults) { - ThrowWhenMacroStabilityDamKernelInputNull(damKernelInput); + MacroStabilityCommonHelper.ThrowWhenMacroStabilityDamKernelInputNull(damKernelInput); var macroStabilityOutput = kernelDataOutput as MacroStabilityOutput; - ThrowWhenMacroStabilityKernelOutputNull(macroStabilityOutput); + MacroStabilityCommonHelper.ThrowWhenMacroStabilityKernelOutputNull(macroStabilityOutput); designResults = new List(); if (macroStabilityOutput?.StabilityOutputItems != null && macroStabilityOutput.StabilityOutputItems.Count > 0) { var macroStabilityOutputItem = macroStabilityOutput.StabilityOutputItems[0]; if (macroStabilityOutputItem != null) { - var designResult = NewDesignResult(damKernelInput, designScenario); - FillDesignResult(macroStabilityOutputItem, designResult); + var designResult = MacroStabilityCommonHelper.NewDesignResult(damKernelInput, designScenario); + MacroStabilityCommonHelper.FillDesignResult(macroStabilityOutputItem, designResult); designResult.StabilityDesignResults.NumberOfIterations = lastIterationIndex; designResult.StabilityDesignResults.UpliftSituation = macroStabilityOutput.UpliftSituation; designResults.Add(designResult); @@ -514,14 +392,14 @@ var isBishopUpliftVan = FailureMechanismParametersMStab.MStabParameters.Model == MStabModelType.BishopUpliftVan; if (isBishopUpliftVan) { - MacroStabilityOutputItem macroStabilityOutputItem; - if (macroStabilityOutput.StabilityOutputItems.Count > 1) + MacroStabilityOutputItem macroStabilityOutputItem = null; + if (macroStabilityOutput != null && macroStabilityOutput.StabilityOutputItems != null && macroStabilityOutput.StabilityOutputItems.Count > 1) { macroStabilityOutputItem = macroStabilityOutput.StabilityOutputItems[1]; if (macroStabilityOutputItem != null) { - var designResult = NewDesignResult(damKernelInput, designScenario); - FillDesignResult(macroStabilityOutputItem, designResult); + var designResult = MacroStabilityCommonHelper.NewDesignResult(damKernelInput, designScenario); + MacroStabilityCommonHelper.FillDesignResult(macroStabilityOutputItem, designResult); designResult.StabilityDesignResults.NumberOfIterations = lastIterationIndex; designResult.StabilityDesignResults.UpliftSituation = macroStabilityOutput.UpliftSituation; designResults.Add(designResult); @@ -556,104 +434,27 @@ // UpliftVan calculation failed. No end results can be given index = 1; } - macroStabilityOutputItem = macroStabilityOutput.StabilityOutputItems[index]; - if (macroStabilityOutputItem != null) + + if (macroStabilityOutput != null) { - var overallResult = NewDesignResult(damKernelInput, designScenario); - FillDesignResult(macroStabilityOutputItem, overallResult); - overallResult.StabilityDesignResults.UpliftSituation = macroStabilityOutput.UpliftSituation; - overallResult.StabilityDesignResults.StabilityModelType = MStabModelType.BishopUpliftVan; - designResults.Add(overallResult); + if (macroStabilityOutput.StabilityOutputItems != null) + { + macroStabilityOutputItem = macroStabilityOutput.StabilityOutputItems[index]; + } + + if (macroStabilityOutputItem != null) + { + var overallResult = MacroStabilityCommonHelper.NewDesignResult(damKernelInput, designScenario); + MacroStabilityCommonHelper.FillDesignResult(macroStabilityOutputItem, overallResult); + overallResult.StabilityDesignResults.UpliftSituation = macroStabilityOutput.UpliftSituation; + overallResult.StabilityDesignResults.StabilityModelType = MStabModelType.BishopUpliftVan; + designResults.Add(overallResult); + } } } } - private DesignResult NewDesignResult(DamKernelInput damKernelInput, DesignScenario designScenario) - { - string soilProfile2DName = damKernelInput.SubSoilScenario.ToString(); - var designResult = new DesignResult(damKernelInput.DamFailureMechanismeCalculationSpecification, - designScenario, damKernelInput.SubSoilScenario.SoilProfile1D, soilProfile2DName) - { - // initialize as failed - CalculationResult = CalculationResult.RunFailed, - StabilityDesignResults = new StabilityDesignResults() - }; - var stabilityDesignResults = new StabilityDesignResults - { - RedesignedSurfaceLine = damKernelInput.Location.SurfaceLine - }; - designResult.ProfileName = soilProfile2DName; - designResult.StabilityDesignResults = stabilityDesignResults; - designResult.CalculationSubDir = damKernelInput.CalculationDir; - return designResult; - } - - private static void FillDesignResult(MacroStabilityOutputItem macroStabilityOutputItem, DesignResult designResult) - { - designResult.BaseFileName = Path.GetFileNameWithoutExtension(macroStabilityOutputItem.ProjectName); - designResult.CalculationSubDir = macroStabilityOutputItem.CalculationPath; - designResult.CalculationResult = macroStabilityOutputItem.CalculationResult; - designResult.StabilityDesignResults.StabilityModelType = macroStabilityOutputItem.StabilityModelType; - if (designResult.CalculationResult == CalculationResult.Succeeded) - { - designResult.StabilityDesignResults.SafetyFactor = macroStabilityOutputItem.SafetyFactor; - } - designResult.StabilityDesignResults.ActiveCenterPoint = - macroStabilityOutputItem.ActiveCenterPoint; - designResult.StabilityDesignResults.ActiveCenterPointRadius = - macroStabilityOutputItem.ActiveCenterPointRadius; - designResult.StabilityDesignResults.ResultSlices = macroStabilityOutputItem.ResultSlices; - - if (macroStabilityOutputItem.StabilityModelType == MStabModelType.UpliftVan || - macroStabilityOutputItem.StabilityModelType == MStabModelType.BishopUpliftVan) - { - designResult.StabilityDesignResults.PassiveCenterPoint = - macroStabilityOutputItem.PassiveCenterPoint; - designResult.StabilityDesignResults.PassiveCenterPointRadius = - macroStabilityOutputItem.PassiveCenterPointRadius; - } - } - /// - /// Throws the when macro stability kernel input is not assigned. - /// - /// The dam macro stability input. - /// - private static void ThrowWhenMacroStabilityKernelInputNull(MacroStabilityKernelDataInput macroStabilityKernelDataInput) - { - if (macroStabilityKernelDataInput == null) - { - throw new NoNullAllowedException(Resources.MacroStabilityKernelWrapper_NoMacroStabilityInputObjectDefined); - } - } - - /// - /// Throws the when macro stability kernel output is not assigned. - /// - /// The dam macro stability output. - /// - private static void ThrowWhenMacroStabilityKernelOutputNull(MacroStabilityOutput macroStabilityOutput) - { - if (macroStabilityOutput == null) - { - throw new NoNullAllowedException(Resources.MacroStabilityKernelWrapper_NoMacroStabilityOutputObjectDefined); - } - } - - /// - /// Throws the when macro stability dam kernel input is not assigned. - /// - /// The dam kernel input. - /// - private static void ThrowWhenMacroStabilityDamKernelInputNull(DamKernelInput damKernelInput) - { - if (damKernelInput == null) - { - throw new NoNullAllowedException(Resources.MacroStabilityKernelWrapper_NoDamInputObjectDefinedForMacroStability); - } - } - - /// /// Calculates the design at point. /// /// The dam kernel input. @@ -687,9 +488,9 @@ { MacroStabilityKernelDataInput macroStabilityKernelDataInput = kernelDataInput as MacroStabilityKernelDataInput; MacroStabilityOutput macroStabilityOutput = kernelDataOutput as MacroStabilityOutput; - ThrowWhenMacroStabilityKernelInputNull(macroStabilityKernelDataInput); - ThrowWhenMacroStabilityKernelOutputNull(macroStabilityOutput); - ThrowWhenMacroStabilityDamKernelInputNull(damKernelInput); + MacroStabilityCommonHelper.ThrowWhenMacroStabilityKernelInputNull(macroStabilityKernelDataInput); + MacroStabilityCommonHelper.ThrowWhenMacroStabilityKernelOutputNull(macroStabilityOutput); + MacroStabilityCommonHelper.ThrowWhenMacroStabilityDamKernelInputNull(damKernelInput); double fosRequired = damKernelInput.Location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope; if (macroStabilityOutput != null) @@ -733,7 +534,7 @@ int iterationIndex, out EmbankmentDesignParameters embankmentDesignParameters) { MacroStabilityKernelDataInput macroStabilityKernelDataInput = kernelDataInput as MacroStabilityKernelDataInput; - ThrowWhenMacroStabilityKernelInputNull(macroStabilityKernelDataInput); + MacroStabilityCommonHelper.ThrowWhenMacroStabilityKernelInputNull(macroStabilityKernelDataInput); lastIterationIndex = iterationIndex; var location = damKernelInput.Location; @@ -782,48 +583,5 @@ return DesignStrategy.NoDesignPossible; } } - - private string GetStabilityInputFileName(DamKernelInput damKernelInput, int iterationIndex, MStabModelType model) - { - // Assume 2D sti-file, then check on type being 1D - string soilGeometryName = damKernelInput.SubSoilScenario.SoilProfile2DName; - string calculationName = DetermineCalculationFilename(damKernelInput.FilenamePrefix, soilGeometryName, iterationIndex); - const string filenameExtension = ".skx"; - string fileName = calculationName + filenameExtension; - string stabilityDirectory = GetStabilityCalculationDirectory(model, damKernelInput.CalculationDir); - return Path.Combine(stabilityDirectory, fileName); - } - - private string DetermineCalculationFilename(string filenamePrefix, string soilGeometryName, int iterationIndex) - { - string calculationName; - if (iterationIndex <= 0) - { - calculationName = $"{filenamePrefix}_Pro({soilGeometryName})"; - } - else - { - calculationName = $"{filenamePrefix}_Pro({soilGeometryName})_Ite({iterationIndex})"; - } - return Regex.Replace(calculationName, @"[\\\/:\*\?""'<>|.]", "_"); - } - - private string GetStabilityCalculationDirectory(MStabModelType model, string projectWorkingPath) - { - string calculationBaseDirectory = projectWorkingPath; - var stabilitySubDir = GetCalculationSubDir(model); - string stabilityDirectory = Path.Combine(calculationBaseDirectory, stabilitySubDir); - if (!Directory.Exists(stabilityDirectory)) - Directory.CreateDirectory(stabilityDirectory); - return stabilityDirectory; - } - - private static string GetCalculationSubDir(MStabModelType model) - { - const string stabilitySubDir = @"Stability\"; - var modelSubDirectory = model.ToString(); - var dir = Path.Combine(stabilitySubDir, modelSubDirectory); - return dir; - } } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/TestFiles/InputFileForStabOutsideBishopAutomaticGrid.xml =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/TestFiles/InputFileForStabOutsideBishopAutomaticGrid.xml (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/TestFiles/InputFileForStabOutsideBishopAutomaticGrid.xml (revision 3800) @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityInwards/BishopGridCreator.cs =================================================================== diff -u -r3699 -r3800 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityInwards/BishopGridCreator.cs (.../BishopGridCreator.cs) (revision 3699) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityInwards/BishopGridCreator.cs (.../BishopGridCreator.cs) (revision 3800) @@ -30,13 +30,14 @@ public class BishopGridCreator { /// Determines the Bishop grid from settings. + /// /// the slip circle definition /// The surface line. /// the the bishop calculation grid - public static BishopCalculationGrid DetermineGridsFromSettings( + public static BishopCalculationGrid DetermineGridsFromSettings(MStabGridPosition gridPosition, SlipCircleDefinition slipCircleDefinition, SurfaceLine2 surfaceLine) { - var bishopCalculationGrid = new BishopCalculationGrid() + var bishopCalculationGrid = new BishopCalculationGrid { IsGridsAutomatic = false, IsTangentLinesAutomatic = false @@ -56,8 +57,17 @@ (slipCircleDefinition.BishopGridHorizontalPointCount - 1); double gridHeight = slipCircleDefinition.BishopGridVerticalPointDistance * (slipCircleDefinition.BishopGridVerticalPointCount - 1); - bishopCalculationGrid.GridXLeft = gridXCoordinate; - bishopCalculationGrid.GridXRight = gridXCoordinate + gridWidth; + if (gridPosition == MStabGridPosition.Right) + { + bishopCalculationGrid.GridXLeft = gridXCoordinate; + bishopCalculationGrid.GridXRight = gridXCoordinate + gridWidth; + + } + else + { + bishopCalculationGrid.GridXLeft = Math.Max(surfaceLine.Geometry[0].X, gridXCoordinate - gridWidth); + bishopCalculationGrid.GridXRight = gridXCoordinate; + } bishopCalculationGrid.GridXCount = slipCircleDefinition.BishopGridHorizontalPointCount; bishopCalculationGrid.GridZBottom = gridYCoordinate; bishopCalculationGrid.GridZTop = gridYCoordinate + gridHeight;