// Copyright (C) Stichting Deltares 2017. 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 Deltares.DamEngine.Data.Design;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard;
using Deltares.DamEngine.Data.Standard.Calculation;
namespace Deltares.DamEngine.Data.General.Results
{
///
/// Contains the results for the design calculations.
///
///
public class DesignResult : ICloneable
{
private string id;
private double xrd;
private double yrd;
private string baseFileName;
private string locationName;
private string scenarioName;
private string profileName;
private double? safetyFactor;
private double? failureProbability;
private CalculationResult calculationResult = CalculationResult.NoRun;
private NwoDesignResults nwoDesignResults;
private StabilityDesignResults stabilityDesignResults;
private PipingDesignResults pipingDesignResults;
///
/// Gets or sets the dam failure mechanisme calculation.
/// Note: this is a placeholder, not to be part of the results as written to xml
///
///
/// The dam failure mechanisme calculation.
///
public DamFailureMechanismeCalculationSpecification DamFailureMechanismeCalculation { get; set; }
///
/// Gets or sets the scenario.
/// Note: this is a placeholder, not to be part of the results as written to xml
///
///
/// The scenario.
///
public DesignScenario Scenario { get; set; }
///
/// Gets or sets the length of the dike as derived value.
/// Note: this is a placeholder, not to be part of the results as written to xml.
/// It is currently used by the DamProjectCalculator.
///
///
/// The length of the dike.
///
public double? DikeLength
{
get
{
double? maxDikeLength = null;
List dikeLengths = new List();
SurfaceLine2 surfaceLine = Scenario.Location.SurfaceLine2;
if (surfaceLine != null)
dikeLengths.Add(surfaceLine.GetDikeLength());
switch (DamFailureMechanismeCalculation.FailureMechanismSystemType)
{
case FailureMechanismSystemType.StabilityInside:
if (stabilityDesignResults.RedesignedSurfaceLine != null)
dikeLengths.Add(stabilityDesignResults.RedesignedSurfaceLine.GetDikeLength());
break;
case FailureMechanismSystemType.Piping:
if (pipingDesignResults.RedesignedSurfaceLine != null)
dikeLengths.Add(pipingDesignResults.RedesignedSurfaceLine.GetDikeLength());
break;
}
foreach (double? dikeLength in dikeLengths)
{
if (dikeLength.HasValue && (!maxDikeLength.HasValue || maxDikeLength < dikeLength))
maxDikeLength = dikeLength;
}
return maxDikeLength;
}
}
///
/// Initializes a new instance of the class.
/// Is only to be used by this.Clone(), nowhere else
///
internal DesignResult()
{
// only for Clone() method
}
///
/// Initializes a new instance of the class.
///
/// The identifier.
/// The dam failure mechanisme calculation specification.
/// The scenario.
/// The soil profile.
/// Name of the soil geometry2 d.
/// Type of the analysis.
/// Index of the nwo result.
public DesignResult(string id, DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification, DesignScenario scenario, SoilProfile1D soilProfile,
string soilGeometry2DName, AnalysisType analysisType, int nwoResultIndex)
{
this.id = id;
xrd = scenario.Location.XRd;
yrd = scenario.Location.YRd;
locationName = scenario.Location.Name;
scenarioName = scenario.LocationScenarioID; // terughalen vanuit csvexport indien echt nodig
baseFileName = "";
DamFailureMechanismeCalculation = damFailureMechanismeCalculationSpecification;
Scenario = scenario;
if (damFailureMechanismeCalculationSpecification != null)
{
switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
{
case FailureMechanismSystemType.StabilityInside:
case FailureMechanismSystemType.StabilityOutside:
profileName = soilGeometry2DName;
if (analysisType == AnalysisType.AdaptNWO)
{
// an index of 0 can also indicate an error message. That has no futher data so check if there actualy is any.
if (scenario.NwoResults.Count > 0)
{
nwoDesignResults = new NwoDesignResults
{
NwoId = scenario.NwoResults[nwoResultIndex].NwoId,
LocationXrdStart = scenario.NwoResults[nwoResultIndex].LocationXrdStart,
LocationYrdStart = scenario.NwoResults[nwoResultIndex].LocationYrdStart,
LocationZrdStart = scenario.NwoResults[nwoResultIndex].LocationZrdStart,
LocationXrdEnd = scenario.NwoResults[nwoResultIndex].LocationXrdEnd,
LocationYrdEnd = scenario.NwoResults[nwoResultIndex].LocationYrdEnd,
LocationZrdEnd = scenario.NwoResults[nwoResultIndex].LocationZrdEnd,
NumberOfIterations = scenario.NwoResults[nwoResultIndex].MStabResults.IterationNumber,
SafetyFactor = scenario.NwoResults[nwoResultIndex].MStabResults.zone1.safetyFactor,
Zone1SafetyFactor = scenario.NwoResults[nwoResultIndex].MStabResults.zone1.safetyFactor,
LocalZone1EntryPointX = scenario.NwoResults[nwoResultIndex].MStabResults.zone1.entryPointXCoordinate,
LocalZone1ExitPointX = scenario.NwoResults[nwoResultIndex].MStabResults.zone1.exitPointXCoordinate,
ResultIndex = nwoResultIndex
};
if (scenario.NwoResults[nwoResultIndex].MStabResults.zone2 != null)
{
nwoDesignResults.Zone2SafetyFactor = scenario.NwoResults[nwoResultIndex].MStabResults.zone2.Value.safetyFactor;
nwoDesignResults.LocalZone2EntryPointX = scenario.NwoResults[nwoResultIndex].MStabResults.zone2.Value.entryPointXCoordinate;
nwoDesignResults.LocalZone2ExitPointX = scenario.NwoResults[nwoResultIndex].MStabResults.zone2.Value.exitPointXCoordinate;
}
baseFileName = scenario.NwoResults[nwoResultIndex].MStabResults.CalculationName;
}
}
else
{
stabilityDesignResults = new StabilityDesignResults();
MStabResults? mstabResults = scenario.GetMStabResults(soilProfile, soilGeometry2DName);
stabilityDesignResults.ResultMessage = scenario.GetResultMessage(soilProfile, soilGeometry2DName);
calculationResult = DetermineStabilityCalculationResult(stabilityDesignResults.ResultMessage, mstabResults);
if (mstabResults != null)
{
baseFileName = mstabResults.Value.CalculationName;
stabilityDesignResults.NumberOfIterations = mstabResults.Value.IterationNumber;
stabilityDesignResults.SafetyFactor = mstabResults.Value.zone1.safetyFactor;
stabilityDesignResults.Zone1SafetyFactor = mstabResults.Value.zone1.safetyFactor;
stabilityDesignResults.LocalZone1EntryPointX = mstabResults.Value.zone1.entryPointXCoordinate;
stabilityDesignResults.LocalZone1ExitPointX = mstabResults.Value.zone1.exitPointXCoordinate;
if (mstabResults.Value.zone2 != null)
{
stabilityDesignResults.Zone2SafetyFactor = mstabResults.Value.zone2.Value.safetyFactor;
stabilityDesignResults.LocalZone2EntryPointX = mstabResults.Value.zone2.Value.entryPointXCoordinate;
stabilityDesignResults.LocalZone2ExitPointX = mstabResults.Value.zone2.Value.exitPointXCoordinate;
}
}
}
stabilityDesignResults.FailureProbability = scenario.GetFailureProbabilityStability(soilProfile, soilGeometry2DName);
failureProbability = stabilityDesignResults.FailureProbability;
stabilityDesignResults.RedesignedSurfaceLine = scenario.GetRedesignedSurfaceLine(soilProfile, soilGeometry2DName);
UpliftSituation? upliftSituation = scenario.GetStabilityUpliftSituation(soilProfile, soilGeometry2DName);
if (upliftSituation != null)
{
stabilityDesignResults.UpliftSituation = upliftSituation;
}
break;
case FailureMechanismSystemType.Piping:
pipingDesignResults = new PipingDesignResults(damFailureMechanismeCalculationSpecification.PipingModelType);
profileName = soilProfile.Name;
pipingDesignResults.FailureProbability = scenario.GetFailureProbabilityPiping(soilProfile, soilGeometry2DName);
failureProbability = pipingDesignResults.FailureProbability;
pipingDesignResults.ResultMessage = scenario.GetResultMessage(soilProfile, soilGeometry2DName);
pipingDesignResults.RedesignedSurfaceLine = scenario.GetRedesignedSurfaceLine(soilProfile, soilGeometry2DName);
UpliftSituation? upliftSituationPiping = scenario.GetStabilityUpliftSituation(soilProfile, soilGeometry2DName);
if (upliftSituationPiping != null)
{
pipingDesignResults.UpliftSituation = upliftSituationPiping;
}
PipingResults? pipingResults = scenario.GetPipingResults(soilProfile, soilGeometry2DName);
if (pipingResults != null)
{
baseFileName = pipingResults.Value.CalculationName;
pipingDesignResults.BlighFactor = pipingResults.Value.BlighPipingFactor;
pipingDesignResults.BlighHcritical = pipingResults.Value.BlighHCritical;
pipingDesignResults.Sellmeijer4ForcesFactor = pipingResults.Value.Sellmeijer4ForcesPipingFactor;
pipingDesignResults.Sellmeijer4ForcesHcritical = pipingResults.Value.Sellmeijer4ForcesHCritical;
pipingDesignResults.SellmeijerVnkFactor = pipingResults.Value.SellmeijerVnkPipingFactor;
pipingDesignResults.SellmeijerVnkHcritical = pipingResults.Value.SellmeijerVnkHCritical;
pipingDesignResults.Wti2017Factor = pipingResults.Value.Wti2017PipingFactor;
pipingDesignResults.Wti2017Hcritical = pipingResults.Value.Wti2017HCritical;
pipingDesignResults.LocalExitPointX = pipingResults.Value.PipingExitPointX;
pipingDesignResults.HeaveFactor = pipingResults.Value.HeaveFactor;
pipingDesignResults.UpliftFactor = pipingResults.Value.UpliftFactor;
}
calculationResult = (pipingDesignResults.SafetyFactor() == null && pipingDesignResults.FailureProbability == null) ? CalculationResult.RunFailed : CalculationResult.Succeeded;
break;
}
}
}
///
/// Gets the identifier.
///
///
/// The identifier.
///
public string Id
{
get { return id; }
}
///
/// Gets the XRD.
///
///
/// The XRD.
///
public double Xrd
{
get
{
return xrd;
}
}
///
/// Gets the yrd.
///
///
/// The yrd.
///
public double Yrd
{
get
{
return yrd;
}
}
//Identifiers, needed to retrace the origin of the result
///
/// Gets the name of the location.
/// For identification purpose
///
///
/// The name of the location.
///
public string LocationName
{
get { return locationName; }
}
///
/// Gets the name of the scenario.
/// For identification purpose
///
///
/// The name of the scenario.
///
public string ScenarioName
{
get { return scenarioName; }
}
///
/// Gets or sets the name of the profile.
/// For identification purpose
///
///
/// The name of the profile.
///
public string ProfileName
{
get
{
return profileName;
}
set
{
profileName = value;
}
}
///
/// Gets or sets the name of the base file.
///
///
/// The name of the base file.
/// Can be used to retrace results files.
///
public string BaseFileName // real result for all.
{
get { return baseFileName; }
set { baseFileName = value; }
}
///
/// Gets or sets the calculation result.
/// This is a derived result.
///
///
/// The calculation result.
///
public CalculationResult CalculationResult
{
get { return calculationResult; }
set { calculationResult = value; }
}
///
/// Gets the safety factor (derived result).
///
///
/// The safety factor.
///
public double? SafetyFactor
{
get
{
return safetyFactor;
}
set
{
safetyFactor = value;
}
}
///
/// Gets or sets the failure probability (derived result).
///
///
/// The failure probability.
///
public double? FailureProbability
{
get
{
return failureProbability;
}
set
{
failureProbability = value;
}
}
///
/// Gets or sets the nwo design results.
///
///
/// The nwo design results.
///
public NwoDesignResults NwoDesignResults
{
get
{
return nwoDesignResults;
}
set
{
nwoDesignResults = value;
}
}
///
/// Gets or sets the stability design results.
///
///
/// The stability design results.
///
public StabilityDesignResults StabilityDesignResults
{
get
{
return stabilityDesignResults;
}
set
{
stabilityDesignResults = value;
}
}
///
/// Gets or sets the piping design results.
///
///
/// The piping design results.
///
public PipingDesignResults PipingDesignResults
{
get
{
return pipingDesignResults;
}
set
{
pipingDesignResults = value;
}
}
///
/// Copy data
///
///
private void Assign(DesignResult designResult)
{
// copy place holders
DamFailureMechanismeCalculation = designResult.DamFailureMechanismeCalculation;
Scenario = designResult.Scenario;
// copy direct data
id = designResult.id;
xrd = designResult.Xrd;
yrd = designResult.Yrd;
baseFileName = designResult.BaseFileName;
locationName = designResult.LocationName;
scenarioName = designResult.ScenarioName;
profileName = designResult.ProfileName;
safetyFactor = designResult.SafetyFactor;
failureProbability = designResult.FailureProbability;
calculationResult = designResult.calculationResult;
nwoDesignResults = new NwoDesignResults();
designResult.NwoDesignResults.CloneProperties(nwoDesignResults);
stabilityDesignResults = new StabilityDesignResults();
designResult.StabilityDesignResults.CloneProperties(stabilityDesignResults);
pipingDesignResults = new PipingDesignResults(DamFailureMechanismeCalculation.PipingModelType);
designResult.PipingDesignResults.CloneProperties(pipingDesignResults);
}
///
/// Make a clone of object
///
///
public object Clone()
{
DesignResult designResult = new DesignResult();
designResult.Assign(this);
return designResult;
}
///
/// Determines the stability calculation run result.
///
/// The result message.
/// The mstab results.
///
private CalculationResult DetermineStabilityCalculationResult(string message, MStabResults? mstabResults)
{
CalculationResult result;
if ((message != null) && message.Contains("FAIL"))
{
result = CalculationResult.UnexpectedError;
}
else
{
// If no failure and no results, then no run has been made
result = mstabResults != null ? CalculationResult.Succeeded : CalculationResult.NoRun;
}
return result;
}
}
}