// 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.IO; using System.Text; using Deltares.DamEngine.Calculators.KernelWrappers.Common; 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.Logging; namespace Deltares.DamEngine.Calculators.DikesDesign { /// /// The Dam Engine design calculator /// public class DesignCalculator { /// /// Performs the design calculation /// /// The dam project data. /// public List Execute(DamProjectData damProjectData) { IKernelWrapper kernelWrapper = KernelWrapperHelper.CreateKernelWrapper(damProjectData.DamProjectCalculationSpecification.CurrentSpecification); if (kernelWrapper == null) { throw new NotImplementedException(Resources.DesignCalculatorKernelNotImplemented); } damProjectData.DesignCalculations = new List(); var calculationMessages = new List(); for (int locationIndex = 0; locationIndex < damProjectData.Dike.Locations.Count; locationIndex++) { var location = damProjectData.Dike.Locations[locationIndex]; for (int subSoilScenarioIndex = 0; subSoilScenarioIndex < location.Segment.SoilProfileProbabilities.Count; subSoilScenarioIndex++) { var soiProfileProbability = location.Segment.SoilProfileProbabilities[subSoilScenarioIndex]; for (int designScenarioIndex = 0; designScenarioIndex < location.Scenarios.Count; designScenarioIndex++) { // Prepare input var damKernelInput = new DamKernelInput(); var projectPath = damProjectData.ProjectPath != "" ? damProjectData.ProjectPath : Directory.GetCurrentDirectory(); damKernelInput.WorkingDir = Path.Combine(projectPath, damProjectData.CalculationMap); damKernelInput.Location = location; damKernelInput.SubSoilScenario = soiProfileProbability; damKernelInput.DesignScenario = location.Scenarios[designScenarioIndex]; damKernelInput.DamFailureMechanismeCalculationSpecification = damProjectData.DamProjectCalculationSpecification.CurrentSpecification; AnalysisType analysisType = DamProjectCalculationSpecification.SelectedAnalysisType; IKernelDataInput kernelDataInput; IKernelDataOutput kernelDataOutput; PrepareResult prepareResult = kernelWrapper.Prepare(damKernelInput, 0, out kernelDataInput, out kernelDataOutput); // Sometimes the kernelDataInput is not created (p.e when soilprofileprobablility is meant for // stability where Piping calc is wanted). In that case, do nothing but just skip. if (prepareResult == PrepareResult.Successful) { switch (analysisType) { case AnalysisType.AdaptGeometry: // PerformDesignCalculation(kernelWrapper, kernelDataInput, kernelDataOutput, // damKernelInput, calculationMessages, damProjectData.DesignCalculations); // break; case AnalysisType.NoAdaption: PerformSingleCalculation(kernelWrapper, kernelDataInput, kernelDataOutput, damKernelInput, calculationMessages, damProjectData.DesignCalculations); break; } } else { if (prepareResult == PrepareResult.NotRelevant) { calculationMessages.Add(new LogMessage(LogMessageType.Info, null, string.Format(Resources.DesignCalculatorIrrelevant, location.Name, soiProfileProbability.ToString(), damKernelInput.DesignScenario.LocationScenarioID))); } if (prepareResult == PrepareResult.Failed) { calculationMessages.Add(new LogMessage(LogMessageType.Error, null, string.Format(Resources.DesignCalculatorPrepareError, location.Name, soiProfileProbability.ToString(), damKernelInput.DesignScenario.LocationScenarioID))); } } } } } return calculationMessages; } private static void PerformSingleCalculation(IKernelWrapper kernelWrapper, IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput, List calculationMessages, List designCalculations) { // Perform validation List locationCalculationMessages = new List(); List validationMessages; int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out validationMessages); if (errorCount > 0) { locationCalculationMessages.Add(new LogMessage(LogMessageType.Error, null, string.Format(Resources.DesignCalculatorValidationFailed, damKernelInput.Location.Name, damKernelInput.SubSoilScenario.ToString(), damKernelInput.DesignScenario.LocationScenarioID))); locationCalculationMessages.AddRange(validationMessages); } else { // Perform calculation kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out locationCalculationMessages); } // Process output calculationMessages.AddRange(locationCalculationMessages); List designResults; StringBuilder sb = new StringBuilder(); foreach (var message in locationCalculationMessages) { sb.Append(message.Message + Environment.NewLine); } string resultMessage = sb.ToString(); kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, resultMessage, out designResults); foreach (var designResult in designResults) { designCalculations.Add(designResult); } } private static void PerformDesignCalculation(IKernelWrapper kernelWrapper, IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput, List calculationMessages, List designCalculations) { } } }