// 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);
}
}
}