// Copyright (C) Stichting Deltares 2016. All rights reserved.
//
// This file is part of Ringtoets.
//
// Ringtoets is free software: you can redistribute it and/or modify
// it under the terms of the GNU 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 General Public License for more details.
//
// You should have received a copy of the GNU 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.Diagnostics;
using System.IO;
using Ringtoets.HydraRing.Calculation.Data;
using Ringtoets.HydraRing.Calculation.Data.Input;
using Ringtoets.HydraRing.Calculation.Data.Output;
using Ringtoets.HydraRing.Calculation.Parsers;
namespace Ringtoets.HydraRing.Calculation.Services
{
///
/// Service that provides methods for performing Hydra-Ring calculations.
///
public class HydraRingCalculationService
{
private static Process hydraRingProcess;
///
/// This method performs a type II calculation via Hydra-Ring:
/// Iterate towards a target probability, provided as reliability index.
///
/// The directory of the HLCD file that should be used for performing the calculation.
/// The id of the ring to perform the calculation for.
/// The to use while executing the calculation.
/// The to use while executing the calculation.
/// The input of the calculation to perform.
/// A on a succesfull calculation, null otherwise.
public virtual TargetProbabilityCalculationOutput PerformCalculation(string hlcdDirectory, string ringId, HydraRingTimeIntegrationSchemeType timeIntegrationSchemeType, HydraRingUncertaintiesType uncertaintiesType, TargetProbabilityCalculationInput targetProbabilityCalculationInput)
{
return PerformCalculation(hlcdDirectory, ringId, timeIntegrationSchemeType, uncertaintiesType,
targetProbabilityCalculationInput, (outputFilePath, outputDatabasePath) =>
TargetProbabilityCalculationParser.Parse(
outputFilePath, targetProbabilityCalculationInput.Section.SectionId));
}
///
/// This method performs a type I calculation via Hydra-Ring:
/// Given a set of random variables, compute the probability of failure.
///
/// The directory of the HLCD file that should be used for performing the calculation.
/// The id of the ring to perform the calculation for.
/// The to use while executing the calculation.
/// The to use while executing the calculation.
/// The input of the calculation to perform.
/// A on a succesfull calculation, null otherwise.
public virtual ExceedanceProbabilityCalculationOutput PerformCalculation(string hlcdDirectory, string ringId, HydraRingTimeIntegrationSchemeType timeIntegrationSchemeType,
HydraRingUncertaintiesType uncertaintiesType,
ExceedanceProbabilityCalculationInput exceedanceProbabilityCalculationInput)
{
return PerformCalculation(hlcdDirectory, ringId, timeIntegrationSchemeType, uncertaintiesType,
exceedanceProbabilityCalculationInput, (outputFilePath, outputDatabasePath) =>
ExceedanceProbabilityCalculationParser.Parse(
outputDatabasePath, exceedanceProbabilityCalculationInput.Section.SectionId));
}
///
/// Cancels any currently running Hydra-Ring calculation.
///
public virtual void CancelRunningCalculation()
{
if (hydraRingProcess != null && !hydraRingProcess.HasExited)
{
hydraRingProcess.StandardInput.WriteLine("b");
}
}
private static T PerformCalculation(string hlcdDirectory, string ringId, HydraRingTimeIntegrationSchemeType timeIntegrationSchemeType, HydraRingUncertaintiesType uncertaintiesType, HydraRingCalculationInput hydraRingCalculationInput, Func parseFunction)
{
var sectionId = hydraRingCalculationInput.Section.SectionId;
// Create a working directory
var workingDirectory = CreateWorkingDirectory(sectionId.ToString());
// Write the initialization script
var hydraRingInitializationService = new HydraRingInitializationService(hydraRingCalculationInput.FailureMechanismType, sectionId, hlcdDirectory, workingDirectory);
File.WriteAllText(hydraRingInitializationService.IniFilePath, hydraRingInitializationService.GenerateInitializationScript());
// Write the database creation script
var hydraRingConfigurationService = new HydraRingConfigurationService(ringId, timeIntegrationSchemeType, uncertaintiesType);
hydraRingConfigurationService.AddHydraRingCalculationInput(hydraRingCalculationInput);
File.WriteAllText(hydraRingInitializationService.DataBaseCreationScriptFilePath, hydraRingConfigurationService.GenerateDataBaseCreationScript());
// Perform the calculation
hydraRingProcess = HydraRingProcessFactory.Create(hydraRingInitializationService.MechanismComputationExeFilePath, hydraRingInitializationService.IniFilePath, workingDirectory);
hydraRingProcess.Start();
hydraRingProcess.WaitForExit();
// Parse and return the output
return parseFunction(hydraRingInitializationService.OutputFilePath, hydraRingInitializationService.OutputDataBasePath);
}
private static string CreateWorkingDirectory(string folderName)
{
var workingDirectory = Path.Combine(Path.GetTempPath(), folderName);
if (Directory.Exists(workingDirectory))
{
Directory.Delete(workingDirectory, true);
}
Directory.CreateDirectory(workingDirectory);
return workingDirectory;
}
}
}