// Copyright (C) Stichting Deltares 2018. 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.Xml.Linq; using Deltares.DamEngine.Calculators.KernelWrappers.Common; using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStabilityCommon; using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces; using Deltares.DamEngine.Calculators.Properties; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.Results; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Logging; using Deltares.DamMacroStability.Calculator; using System.IO; namespace Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStabilityOutwards { /// /// Class for the wrapper around the Stability Outwards calculator /// /// public class DamMacroStabilityOutwardsKernelWrapper : IKernelWrapper { /// /// Gets or sets the failure mechanisme paramaters for mstab. /// /// /// The failure mechanisme paramaters mstab. /// public FailureMechanismParametersMStab FailureMechanismParametersMStab { get; set; } /// /// Gets or sets the index of the iteration. /// /// /// The index of the iteration. /// public int IterationIndex { 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) { var damMacroStabilityOutput = new DamMacroStabilityOutput() { StabilityOutputItems = new List(), CalculationResult = CalculationResult.NoRun }; kernelDataOutput = damMacroStabilityOutput; // Note: as segments and thus SubSoilScenario are generally divided into Piping versus Stability, // the actual SegmentFailureMechanismType would be set to StabilityInside rather than StabilityOutside // So check for both types. if (damKernelInput.SubSoilScenario.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityOutside || damKernelInput.SubSoilScenario.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityInside) { // Make sure the gridposition is Left. FailureMechanismParametersMStab.MStabParameters.GridPosition = MStabGridPosition.Left; if (string.IsNullOrEmpty(damKernelInput.WorkingDir)) { FailureMechanismParametersMStab.ProjectWorkingPath = Directory.GetCurrentDirectory(); } else { FailureMechanismParametersMStab.ProjectWorkingPath = damKernelInput.WorkingDir; } if (damKernelInput.SubSoilScenario.SoilProfileType == SoilProfileType.ProfileTypeStiFile) { damKernelInput.SubSoilScenario.StiFileName = Path.Combine( damKernelInput.Location.StabilityOptions.SoilGeometries2DPath, damKernelInput.SubSoilScenario.StiFileName); } var damMacroStabilityInput = new DamMacroStabilityInput() { DGeoStabilityExePath = FailureMechanismParametersMStab.DGeoStabilityExePath, DGeoStabilityInputFileName = DamMacroStabilityUtils.GetStabilityInputFileName(damKernelInput, iterationIndex, FailureMechanismParametersMStab.MStabParameters.Model, FailureMechanismParametersMStab.ProjectWorkingPath), FailureMechanismParametersMStab = FailureMechanismParametersMStab }; kernelDataInput = damMacroStabilityInput; // Write xml file XDocument xmlDocument = CreateMstabDamXmlDocument(damKernelInput, damMacroStabilityInput); // Use xml file to create sti file CreateStiFile(xmlDocument); return PrepareResult.Successful; } kernelDataInput = null; return PrepareResult.NotRelevant; } /// /// 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 damMacroStabilityOutputItem = new DamMacroStabilityOutputItem(); var zone1 = new DamMacroStabilityOutputItem.ResultsSingleZone { SafetyFactor = results[0].Zone1.SafetyFactor, CircleSurfacePointLeftXCoordinate = results[0].Zone1.CircleSurfacePointLeftXCoordinate, CircleSurfacePointRightXCoordinate = results[0].Zone1.CircleSurfacePointRightXCoordinate, EntryPointXCoordinate = results[0].Zone1.EntryPointXCoordinate, ExitPointXCoordinate = results[0].Zone1.ExitPointXCoordinate }; damMacroStabilityOutputItem.Zone1Results = zone1; if (results[0].Zone2 != null) { var zone2 = new DamMacroStabilityOutputItem.ResultsSingleZone { SafetyFactor = results[0].Zone1.SafetyFactor, CircleSurfacePointLeftXCoordinate = results[0].Zone1.CircleSurfacePointLeftXCoordinate, CircleSurfacePointRightXCoordinate = results[0].Zone1.CircleSurfacePointRightXCoordinate, EntryPointXCoordinate = results[0].Zone1.EntryPointXCoordinate, ExitPointXCoordinate = results[0].Zone1.ExitPointXCoordinate }; damMacroStabilityOutputItem.Zone2Results = zone2; } damMacroStabilityOutput.StabilityOutputItems.Add(damMacroStabilityOutputItem); } } internal XDocument CreateMstabDamXmlDocument(DamKernelInput damKernelInput, DamMacroStabilityInput kernelDataInput) { var stabilityProjectFilename = kernelDataInput.DGeoStabilityInputFileName; var scenario = damKernelInput.DesignScenario; var subSoilScenario = damKernelInput.SubSoilScenario; var requiredSafetyFactor = scenario.RequiredSafetyFactorStabilityOuterSlope?? scenario.Location.ModelFactors.RequiredSafetyFactorStabilityOuterSlope; if (requiredSafetyFactor == null) { throw new MacroStabilityException(Resources.DamMacroStabilityOutwardsKernelWrapper_Prepare_NoRequiredSafetyFactor); } List errorMessages; XDocument mstabXml = MStabXmlDoc.CreateMStabXmlDoc(stabilityProjectFilename, scenario, subSoilScenario, null, requiredSafetyFactor.Value, kernelDataInput.FailureMechanismParametersMStab, 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 results. /// public void PostProcess(DamKernelInput damKernelInput, IKernelDataOutput kernelDataOutput, string resultMessage, out List designResults) { DamMacroStabilityOutput damMacroStabilityOutput = kernelDataOutput as DamMacroStabilityOutput; if (damKernelInput == null) { throw new NoNullAllowedException(Resources.DamMacroStabilityKernelWrapper_StabilityCalculator_NoInputObjectDefinedForMacroStability); } if (damMacroStabilityOutput == null) { throw new NoNullAllowedException(Resources.DamMacroStabilityKernelWrapper_PostProcess_NoOutputObjectDefinedForMacroStability); } string soilProfile2DName = damKernelInput.SubSoilScenario.ToString(); designResults = new List(); var designResult = new DesignResult(damKernelInput.DamFailureMechanismeCalculationSpecification, damKernelInput.DesignScenario, damKernelInput.SubSoilScenario.SoilProfile1D, soilProfile2DName, DamProjectCalculationSpecification.SelectedAnalysisType) { // initialize as failed CalculationResult = CalculationResult.RunFailed }; // Outwards can have only one result as BishopUpliftVan as model is not allowed if (damMacroStabilityOutput.StabilityOutputItems.Count == 1) { var damMacroStabilityOutputItem = damMacroStabilityOutput.StabilityOutputItems[0]; var stabilityDesignResults = new StabilityDesignResults { Zone1SafetyFactor = damMacroStabilityOutputItem.Zone1Results.SafetyFactor, LocalZone1EntryPointX = damMacroStabilityOutputItem.Zone1Results.EntryPointXCoordinate, LocalZone1ExitPointX = damMacroStabilityOutputItem.Zone1Results.ExitPointXCoordinate }; stabilityDesignResults.SafetyFactor = stabilityDesignResults.Zone1SafetyFactor; if (damMacroStabilityOutputItem.Zone2Results != null) { var zone2 = (DamMacroStabilityOutputItem.ResultsSingleZone)damMacroStabilityOutputItem.Zone2Results; stabilityDesignResults.Zone2SafetyFactor = zone2.SafetyFactor; stabilityDesignResults.LocalZone2EntryPointX = zone2.EntryPointXCoordinate; stabilityDesignResults.LocalZone2ExitPointX = zone2.ExitPointXCoordinate; stabilityDesignResults.SafetyFactor = Math.Min(damMacroStabilityOutputItem.Zone1Results.SafetyFactor, zone2.SafetyFactor); } designResult.StabilityDesignResults = stabilityDesignResults; designResult.CalculationResult = damMacroStabilityOutputItem.CalculationResult; } designResults.Add(designResult); } } }