using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Xml.Linq; using Deltares.DamEngine.Calculators.KernelWrappers.Common; using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStability.Assemblers; using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces; 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.Logging; using Deltares.DamMacroStability.Calculator; namespace Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStability { public class DamMacroStabilityKernelWrapper : IKernelWrapper { private const string DamMacroStabilityFolder = @".\KernelWrappers\DamMacroStability"; private const string DGeoStabilityExe = "DGeoStability.exe"; /// /// 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, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput) { // ToDo zant set stiFileName // string stabilityDirectory = GetStabilityCalculationDirectory(); // string filenameExtension = GetFilenameExtension(); // string fileName = calculationName + filenameExtension; // var stabilityProjectFilename = Path.Combine(stabilityDirectory, fileName); const string testFolder = @"..\..\Deltares.DamEngine.Calculators.Tests\Files\MacroStability"; // Relative paths in ini file do not work yet in DGeoStability 16.2. This is fixed in 18.1. var absoluteFolder = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), testFolder)); var stiFileName = Path.Combine(absoluteFolder, "test.sti"); var damPipingInput = new DamMacroStabilityInput() { DGeoStabilityExePath = Path.Combine(DamMacroStabilityFolder, DGeoStabilityExe), DGeoStabilityInputFileName = stiFileName }; kernelDataInput = damPipingInput; kernelDataOutput = new DamMacroStabilityOutput(); // Write xml file XDocument xmlDocument = CreateMstabDamXmlDocument(damKernelInput, damPipingInput); // Use xml file to create sti file CreateStiFile(xmlDocument); return PrepareResult.Successful; } /// /// Validates the specified kernel data input. /// /// The kernel data input. /// The kernel data output. /// The return messages. /// /// Number of errors that prevent a calculation /// public int Validate(IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, out List messages) { var calculator = StabilityCalculator(kernelDataInput); //ToDo zant calculator has no Validate. // List kernelMessages = calculator.Validate(); messages = new List(); // foreach (string stringMessage in kernelMessages) // { // messages.Add(new LogMessage() { Message = stringMessage, MessageType = LogMessageType.Error }); // } return messages.Count; } /// /// Executes the kernel. /// /// The kernel data input. /// The kernel data output. /// The return messages. public void Execute(IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, out List messages) { DamMacroStabilityOutput damMacroStabilityOutput = (DamMacroStabilityOutput) kernelDataOutput; messages = new List(); // start calculation var calculator = StabilityCalculator(kernelDataInput); calculator.Calculate(); // get results var results = calculator.GetResults(); if (results.Count > 0) { var zone1 = new DamMacroStabilityOutput.ResultsSingleZone(); zone1.SafetyFactor = results[0].Zone1.SafetyFactor; zone1.CircleSurfacePointLeftXCoordinate = results[0].Zone1.CircleSurfacePointLeftXCoordinate; zone1.CircleSurfacePointRightXCoordinate = results[0].Zone1.CircleSurfacePointRightXCoordinate; zone1.EntryPointXCoordinate = results[0].Zone1.EntryPointXCoordinate; zone1.ExitPointXCoordinate = results[0].Zone1.ExitPointXCoordinate; damMacroStabilityOutput.Zone1 = zone1; if (results[0].Zone2 != null) { var zone2 = new DamMacroStabilityOutput.ResultsSingleZone(); zone2.SafetyFactor = results[0].Zone1.SafetyFactor; zone2.CircleSurfacePointLeftXCoordinate = results[0].Zone1.CircleSurfacePointLeftXCoordinate; zone2.CircleSurfacePointRightXCoordinate = results[0].Zone1.CircleSurfacePointRightXCoordinate; zone2.EntryPointXCoordinate = results[0].Zone1.EntryPointXCoordinate; zone2.ExitPointXCoordinate = results[0].Zone1.ExitPointXCoordinate; damMacroStabilityOutput.Zone2 = zone2; } } } internal XDocument CreateMstabDamXmlDocument(DamKernelInput damKernelInput, DamMacroStabilityInput kernelDataInput) { const string testFolder = @"..\..\Deltares.DamEngine.Calculators.Tests\Files\MacroStability"; // var stabilityProjectFilename = Path.Combine(testFolder, "test.sti"); // var soilDbName = var geometryFileName = Path.Combine(testFolder, "DWP_1.sti"); var stabilityProjectFilename = kernelDataInput.DGeoStabilityInputFileName; var scenario = damKernelInput.DesignScenario; var subSoilScenario = damKernelInput.SubSoilScenario; var riverLevel = scenario.RiverLevel; var surfaceLine = scenario.Location.SurfaceLine; var trafficLoad = scenario.Location.StabilityOptions.TrafficLoad; var requiredSafetyFactor = scenario.RequiredSafetyFactorStabilityInnerSlope; if (requiredSafetyFactor == null) { throw new MacroStabilityException("Required safety factor must be specified"); } List errorMessages; // ToDo zant scenario.Location.StabilityOptions.MapForSoilGeometries2D = testFolder; scenario.Location.SoildatabaseName = Path.Combine(testFolder, "DAM Tutorial Design0.soilmaterials.mdb"); scenario.Location.DikeEmbankmentMaterial = "dijksmateriaal_klei"; XDocument mstabXml = MStabXmlDoc.CreateMStabXmlDoc(stabilityProjectFilename, scenario, subSoilScenario, riverLevel, null, surfaceLine, trafficLoad, requiredSafetyFactor.Value, out errorMessages); mstabXml.Save(stabilityProjectFilename + ".xml"); return mstabXml; } internal void CreateStiFile(XDocument xmlDocument) { DGSMStabDAMInterface mstabDamDll = new DGSMStabDAMInterface(); var result = mstabDamDll.CreateProjectFile(xmlDocument.ToString()); if (result > 0) { string errorMessage = mstabDamDll.ErrorMessage(); throw new MacroStabilityException(errorMessage); } } internal static StabilityCalculator StabilityCalculator(IKernelDataInput kernelDataInput) { DamMacroStabilityInput damMacroStabilityInput = kernelDataInput as DamMacroStabilityInput; if (damMacroStabilityInput == null) { throw new NoNullAllowedException(Resources.DamMacroStabilityKernelWrapper_StabilityCalculator_NoInputObjectDefinedForMacroStability); } var calculator = new StabilityCalculator { ProjectName = damMacroStabilityInput.DGeoStabilityInputFileName, DGeoStabilityExePath = damMacroStabilityInput.DGeoStabilityExePath }; return calculator; } /// /// Fills the design results with the kernel output. /// /// The dam kernel input. /// The kernel data output. /// The result message. /// The design result. /// public void PostProcess(DamKernelInput damKernelInput, IKernelDataOutput kernelDataOutput, string resultMessage, out DesignResult designResult) { DamMacroStabilityOutput damPipingOutput = kernelDataOutput as DamMacroStabilityOutput; if (damPipingOutput == null) { throw new NoNullAllowedException(Resources.DamMacroStabilityKernelWrapper_PostProcess_NoOutputObjectDefinedForSellmeijer4Forces); } // TODO: this is just fake data string id = "id"; string soilProfile2DName = "soilProfile2DName"; var d = new DamFailureMechanismeCalculationSpecification(); var s = new DesignScenario(); s.Location = new Location(); var p = new SoilProfile1D(); designResult = new DesignResult(d, s, p, soilProfile2DName, AnalysisType.NoAdaption); var stabilityDesignResults = new StabilityDesignResults(); stabilityDesignResults.Zone1SafetyFactor = damPipingOutput.Zone1.SafetyFactor; stabilityDesignResults.LocalZone1EntryPointX = damPipingOutput.Zone1.EntryPointXCoordinate; stabilityDesignResults.LocalZone1ExitPointX = damPipingOutput.Zone1.ExitPointXCoordinate; stabilityDesignResults.SafetyFactor = stabilityDesignResults.Zone1SafetyFactor; if (damPipingOutput.Zone2 != null) { var zone2 = (DamMacroStabilityOutput.ResultsSingleZone) damPipingOutput.Zone2; stabilityDesignResults.Zone2SafetyFactor = zone2.SafetyFactor; stabilityDesignResults.LocalZone2EntryPointX = zone2.EntryPointXCoordinate; stabilityDesignResults.LocalZone2ExitPointX = zone2.ExitPointXCoordinate; stabilityDesignResults.SafetyFactor = Math.Min(damPipingOutput.Zone1.SafetyFactor, zone2.SafetyFactor); } designResult.StabilityDesignResults = stabilityDesignResults; } } }