//-----------------------------------------------------------------------
//
// Copyright (c) 2011 Deltares. All rights reserved.
//
// B.S.T.I.M. The
// tom.the@deltares.nl
// 03-02-2011
// Toplevel Calculator object which will perform all single calculations
//-----------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Deltares.Geometry;
using Deltares.Geotechnics;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Standard;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.IO.Xml;
using Deltares.Standard.Logging;
namespace Deltares.Dam.Data
{
public class DamProjectCalculator
{
private readonly DamProjectData damProjectData;
private readonly Object lockObject = new object();
private int maxCalculationCores = 255;
private string slopeWProgramPath = "";
private string mStabProgramPath = "";
private string calculationBaseDirectory = "";
///
/// Constructor
///
///
public DamProjectCalculator(DamProjectData damProjectData)
{
this.damProjectData = damProjectData;
}
///
/// Base directory where the project is stored
/// Needed to find the 2d geometries
///
public string ProjectDataDirectory { get; set; }
public ProgressDelegate Progress { get; set; }
///
/// Properties
///
public string CalculationBaseDirectory
{
get
{
return calculationBaseDirectory;
}
set
{
calculationBaseDirectory = value;
}
}
public string MStabProgramPath
{
get
{
return mStabProgramPath;
}
set
{
mStabProgramPath = value;
}
}
public string SlopeWProgramPath
{
get
{
return slopeWProgramPath;
}
set
{
slopeWProgramPath = value;
}
}
public int MaxCalculationCores
{
get
{
return maxCalculationCores;
}
set
{
maxCalculationCores = value;
}
}
///
/// Validate if all parameters are available for calculation of project
///
public void ValidateGeneral()
{
// ToDo make this intelligent depending on the specification
ThrowHelper.ThrowWhenConditionIsTrue("No actual calculation specified.",
() => damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications.Count == 0);
}
///
/// Validate if all parameters are available for calculation of project
///
public void ValidateSpecification()
{
// ToDo make this intelligent depending on the specification
if (damProjectData.ProgramType == ProgramType.MStab)
{
ThrowHelper.ThrowIfFileNotExist(MStabProgramPath, StringResourceNames.MStabExecutableFileNameNotFound);
}
if (damProjectData.ProgramType == ProgramType.SlopeW)
{
ThrowHelper.ThrowIfFileNotExist(SlopeWProgramPath, StringResourceNames.SlopeWExecutableFileNameNotFound);
}
}
///
/// Perform the calculations
///
public List> Calculate(DamProjectData damProjectData, IList scenarios)
{
foreach (var scenario in scenarios)
{
foreach (var dike in damProjectData.WaterBoard.Dikes)
{
if (dike.Locations.Contains(scenario.Location))
{
dike.UpdateLocation(scenario.Location);
break;
}
}
}
ValidateGeneral();
Parallel.Run((IList) scenarios, RunScenario, Progress, MaxCalculationCores);
var allCalculationResults = scenarios.Select(scenario => scenario.CalculationResults).ToList();
PostprocessForStabilityUpliftVanBishop(ref allCalculationResults);
this.damProjectData.UpdateDesignCalculations();
return allCalculationResults;
}
///
/// Determine where lowest uplift factor occurs and the value of that factor
///
///
///
///
///
///
///
///
public double? GetLowestUpliftFactor(SurfaceLine2 surfaceLine, SoilProfile1D soilProfile, string soilGeometry2DName, PLLines plLines, Location location)
{
var upliftLocationDeterminator = new UpliftLocationDeterminator()
{
SurfaceLine = surfaceLine,
SoilProfile = soilProfile,
SoilGeometry2DName = soilGeometry2DName,
SoilBaseDB = location.SoilbaseDB,
SoilList = location.SoilList,
DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(),
PLLines = plLines,
XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin
};
UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationAtWithLowestUpliftFactor();
if (upliftLocationAndResult != null)
{
return upliftLocationAndResult.UpliftFactor;
}
return null;
}
///
/// Determines whether it is a combined stability bishop and liftvan calculation.
///
/// The calculation specification.
///
/// true if it is a stability bishop and liftvan calculation; otherwise, false.
///
private bool IsStabilityBishopLiftVanCalculation(DamFailureMechanismeCalculationSpecification calculationSpecification)
{
return ((calculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) &&
((MStabModelType) calculationSpecification.CalculationModel == MStabModelType.BishopUpliftVan));
}
///
/// Calculate one scenario
///
///
private void RunScenario(object scenarioTask)
{
var scenario = (Scenario) scenarioTask;
var scenarioName = scenario.Location.Name;
Debug.WriteLine(String.Format("Start thread for location '{0}'", scenarioName));
DataEventPublisher.InvokeWithoutPublishingEvents(() =>
{
Location oldLocation = null;
try
{
oldLocation = scenario.Location;
var scenarioId = scenario.LocationScenarioID;
Debug.WriteLine("Location '{0}', scenario '{1}'", scenarioName, scenarioId);
scenario.ClearResults();
scenario.ClearErrors();
CloneLocationOnScenario(scenario);
if (scenario.PlLineOffsetBelowDikeToeAtPolder.HasValue)
{
scenario.Location.PlLineOffsetBelowDikeToeAtPolder = scenario.PlLineOffsetBelowDikeToeAtPolder.Value;
}
if (scenario.PlLineOffsetBelowDikeTopAtPolder.HasValue)
{
scenario.Location.PlLineOffsetBelowDikeTopAtPolder = scenario.PlLineOffsetBelowDikeTopAtPolder.Value;
}
if (scenario.PlLineOffsetBelowDikeTopAtRiver.HasValue)
{
scenario.Location.PlLineOffsetBelowDikeTopAtRiver = scenario.PlLineOffsetBelowDikeTopAtRiver.Value;
}
if (scenario.PlLineOffsetBelowShoulderBaseInside.HasValue)
{
scenario.Location.PlLineOffsetBelowShoulderBaseInside = scenario.PlLineOffsetBelowShoulderBaseInside.Value;
}
if (scenario.PlLineOffsetBelowDikeCrestMiddle.HasValue)
{
scenario.Location.PlLineOffsetBelowDikeCrestMiddle = scenario.PlLineOffsetBelowDikeCrestMiddle;
}
if (scenario.PlLineOffsetFactorBelowShoulderCrest.HasValue)
{
scenario.Location.PlLineOffsetFactorBelowShoulderCrest = scenario.PlLineOffsetFactorBelowShoulderCrest;
}
if (scenario.UsePlLineOffsetBelowDikeCrestMiddle.HasValue)
{
scenario.Location.UsePlLineOffsetBelowDikeCrestMiddle = scenario.UsePlLineOffsetBelowDikeCrestMiddle;
}
if (scenario.UsePlLineOffsetFactorBelowShoulderCrest.HasValue)
{
scenario.Location.UsePlLineOffsetFactorBelowShoulderCrest = scenario.UsePlLineOffsetFactorBelowShoulderCrest;
}
if (scenario.HeadPl3.HasValue)
{
scenario.Location.HeadPl3 = scenario.HeadPl3.Value;
}
if (scenario.HeadPl4.HasValue)
{
scenario.Location.HeadPl4 = scenario.HeadPl4.Value;
}
var selectedKernelType = StabilityKernelType.DamClassic;
var damProjectCalculationSpecification = damProjectData.DamProjectCalculationSpecification;
var spec = damProjectCalculationSpecification.DamCalculationSpecifications.First();
if (spec != null)
{
selectedKernelType = spec.StabilityKernelType;
}
if (DetermineStabilityUpliftForScenarios(scenario, selectedKernelType))
{
// Save the results after each calculation, because these will be deleted in the next calculation
var calculationresults = new List();
foreach (var calculationSpecification in damProjectCalculationSpecification.DamCalculationSpecifications)
{
var selectedProbabilisticType = damProjectCalculationSpecification.SelectedProbabilisticType;
var analysisType = DamProjectCalculationSpecification.SelectedAnalysisType;
Debug.WriteLine("Location '{0}', scenario '{1}' 10", scenarioName, scenarioId);
ValidateSpecification();
if (IsStabilityBishopLiftVanCalculation(calculationSpecification))
{
Debug.WriteLine("Location '{0}', scenario '{1}' 11", scenarioName, scenarioId);
CalculateStabilityBishopUpliftvanForScenario(scenario, calculationSpecification, selectedProbabilisticType, analysisType);
}
else
{
Debug.WriteLine("Location '{0}', scenario '{1}' 15", scenarioName, scenarioId);
CalculateOneCalculationTypeForScenario(scenario, calculationSpecification, selectedProbabilisticType, analysisType);
}
Debug.WriteLine("Location '{0}', scenario '{1}' 20", scenarioName, scenarioId);
calculationresults.AddRange(scenario.CalculationResults);
}
// Assign the combined results to the scenario
scenario.CalculationResults.Clear();
scenario.CalculationResults.AddRange(calculationresults);
}
}
catch (Exception exception)
{
scenario.Errors.Add(exception.Message);
}
finally
{
if( oldLocation != null)
{
scenario.Location = oldLocation;
}
}
});
}
private void CloneLocationOnScenario(Scenario scenario)
{
lock (lockObject)
{
// TODO missing clone method for Location. This is a dirty way of performing a clone.
var locationUsedInCalculation = new XmlSerializer().SerializeToString(scenario.Location);
var location = new XmlDeserializer().XmlDeserializeFromString(locationUsedInCalculation);
scenario.Location = location;
}
}
///
/// Calculates combined stability bishop and upliftvan for scenario.
///
/// The scenario.
/// The calculation specification.
/// Type of the probabilistic.
/// Type of the analysis.
private void CalculateStabilityBishopUpliftvanForScenario(Scenario scenario, DamFailureMechanismeCalculationSpecification calculationSpecification, ProbabilisticType probabilisticType, AnalysisType analysisType)
{
var bishopCalculationSpecification = new DamFailureMechanismeCalculationSpecification();
bishopCalculationSpecification.Assign(calculationSpecification);
bishopCalculationSpecification.CalculationModel = MStabModelType.Bishop;
var liftvanCalculationSpecification = new DamFailureMechanismeCalculationSpecification();
liftvanCalculationSpecification.Assign(calculationSpecification);
liftvanCalculationSpecification.CalculationModel = MStabModelType.UpliftVan;
// Make sure check on uplift is performed before doing UpliftVan calculation
liftvanCalculationSpecification.FailureMechanismeParamatersMStab.IsStabilityCheckOnUplift = true;
// First perform calculate Bishop
CalculateOneCalculationTypeForScenario(scenario, bishopCalculationSpecification, probabilisticType, analysisType);
// Save the results, because these will be deleted in the next calculation
var calculationresults = new List();
calculationresults.AddRange(scenario.CalculationResults);
// Now run LiftVan calculation
CalculateOneCalculationTypeForScenario(scenario, liftvanCalculationSpecification, probabilisticType, analysisType);
// Combine Bishop and Liftvan results and assign them to the scenario
calculationresults.AddRange(scenario.CalculationResults);
scenario.CalculationResults.Clear();
scenario.CalculationResults.AddRange(calculationresults);
}
///
/// Calculates one calculation type for scenario.
///
/// The scenario.
/// The dam failure mechanisme calculation specification.
/// Type of the probabilistic.
/// Type of the analysis.
private void CalculateOneCalculationTypeForScenario(
Scenario scenario,
DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification,
ProbabilisticType probabilisticType,
AnalysisType analysisType)
{
if (damProjectData.WaterBoard.Dikes.Count > 1)
{
throw new Exception("Not possible to calculate with more than one dike");
}
var dike = damProjectData.WaterBoard.Dikes[0];
var damProjectCalculatorLogBuilder = new DamProjectCalculatorCsvExportDataBuilder
(
dike,
scenario,
damFailureMechanismeCalculationSpecification,
analysisType,
probabilisticType
);
scenario.ClearResults();
scenario.ClearErrors();
var damFailureMechanismeCalculator = new DamFailureMechanismeCalculator(
damProjectData.ProgramType,
damFailureMechanismeCalculationSpecification,
MStabProgramPath,
SlopeWProgramPath,
dike.MapForSoilGeometries2D,
probabilisticType);
damFailureMechanismeCalculator.CalculationBaseDirectory = CalculationBaseDirectory;
if (analysisType == AnalysisType.AdaptNWO)
{
damFailureMechanismeCalculator.NonWaterRetainingObject = dike.NonWaterRetainingObjects[0];
}
if (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside ||
damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityOutside)
{
StabilityCalculator.ModelSubDirectory = damFailureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters.Model.ToString();
}
try
{
damFailureMechanismeCalculator.Calculate(analysisType, scenario);
foreach (var error in scenario.Errors)
{
var logMessage = new LogMessage(LogMessageType.Error, null, error);
damFailureMechanismeCalculator.ErrorMessages.Add(logMessage);
}
foreach (var errorMessage in damFailureMechanismeCalculator.ErrorMessages)
{
LogManager.Messages.Add(errorMessage);
}
var recordIndex = 0;
var firstNwoSoilProfileProbability = true;
var validSoilProfileProbabilities = DamFailureMechanismeCalculator.SelectProbabilitiesForFailureMechanism(
damFailureMechanismeCalculationSpecification.FailureMechanismSystemType, scenario.Location.Segment.SoilProfileProbabilities);
foreach (var soilProfileProbability in validSoilProfileProbabilities)
{
if (analysisType == AnalysisType.AdaptNWO)
{
if (firstNwoSoilProfileProbability)
{
// for NWO, only add results for every first soilProfileProbability as the others are already part of the nwo results.
foreach (var nwoResult in scenario.NwoResults)
{
var resultMessage = scenario.GetResultMessage(
nwoResult.SoilProfileProbability.SoilProfile,
nwoResult.SoilProfileProbability.SoilGeometry2DName);
// The error message can contain "," and ";" and should therefor be surrounded with double quotes, so it will be read correctly as a scv file
damProjectCalculatorLogBuilder.Append(
@"""",
++recordIndex,
" - ",
resultMessage,
" - ",
nwoResult.NwoId,
" - ",
nwoResult.LocationXrdStart,
" - ",
nwoResult.MStabResults.CalculationName,
@""""
);
scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(nwoResult.SoilProfileProbability, scenario.NwoResults.IndexOf(nwoResult)));
scenario.CalculationResult = CalculationResult.Succeeded;
}
foreach (var error in scenario.Errors)
{
damProjectCalculatorLogBuilder.Append(error);
scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(soilProfileProbability));
scenario.CalculationResult = CalculationResult.Succeeded;
}
firstNwoSoilProfileProbability = false;
}
else
{
if (scenario.CalculationResult != CalculationResult.NoRun)
{
// The error message can contain "," and ";" and should therefor be surrounded with double quotes, so it will be read correctly as a csv file
string resultMessage = scenario.GetResultMessage(soilProfileProbability.SoilProfile,
soilProfileProbability.SoilGeometry2DName);
damProjectCalculatorLogBuilder.Append(
@"""",
++recordIndex,
" - ",
resultMessage,
@""""
);
scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(soilProfileProbability));
}
scenario.CalculationResult = CalculationResult.Succeeded;
}
}
else
{
// The error message can contain "," and ";" and should therefor be surrounded with double quotes, so it will be read correctly as a scv file
var resultMessage = scenario.GetResultMessage(
soilProfileProbability.SoilProfile,
soilProfileProbability.SoilGeometry2DName);
damProjectCalculatorLogBuilder.Append(
@"""",
++recordIndex,
" - ",
resultMessage,
@""""
);
scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(soilProfileProbability, damFailureMechanismeCalculationSpecification.StabilityKernelType));
scenario.CalculationResult = CalculationResult.Succeeded;
}
}
}
catch (Exception exception)
{
damProjectCalculatorLogBuilder.Append("Error: ", exception.Message);
var innerException = exception.InnerException;
while (innerException != null)
{
damProjectCalculatorLogBuilder.Append(": ", innerException.Message);
innerException = innerException.InnerException;
}
foreach (var error in scenario.Errors)
{
var logMessage = new LogMessage(LogMessageType.Error, null, error);
LogManager.Messages.Add(logMessage);
}
foreach (var errorMessage in damFailureMechanismeCalculator.ErrorMessages)
{
LogManager.Messages.Add(errorMessage);
}
foreach (var soilProfileProbability in scenario.Location.Segment.SoilProfileProbabilities)
{
if (soilProfileProbability.SegmentFailureMechanismType == null ||
soilProfileProbability.SegmentFailureMechanismType == damFailureMechanismeCalculationSpecification.FailureMechanismSystemType)
{
scenario.CalculationResults.Add(damProjectCalculatorLogBuilder.Build(soilProfileProbability));
scenario.CalculationResult = CalculationResult.UnexpectedError;
}
}
throw;
}
}
///
/// Determine for each scenario if uplift occurs
///
///
///
///
private bool DetermineStabilityUpliftForScenarios(Scenario scenario, StabilityKernelType stabilityKernelType)
{
if (stabilityKernelType == StabilityKernelType.AdvancedWti ||
stabilityKernelType == StabilityKernelType.AdvancedDotNet)
{
return true;
}
var res = true;
Dike dike = damProjectData.WaterBoard.Dikes[0];
double upliftCriterion = scenario.GetUpliftCriterionStability(scenario.Location.ModelFactors.UpliftCriterionStability);
foreach (var soilProfileProbability in scenario.Location.Segment.SoilProfileProbabilities)
{
if (soilProfileProbability.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityInside ||
soilProfileProbability.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityOutside ||
soilProfileProbability.SegmentFailureMechanismType == null)
{
try
{
SurfaceLine2 surfaceLineWithNewHeight = DamFailureMechanismeCalculator.RedesignSurfaceLineHeight(FailureMechanismSystemType.StabilityInside, scenario,
scenario.Location.LocalXZSurfaceLine2);
// for scenarios the uplift should be calculated with the redesigned height, else a problem may occur with the waterlevel above the dike
var upliftSituation = new UpliftSituation();
PLLines plLines = CreateAllPLLines(out upliftSituation, scenario.RiverLevel,
scenario.RiverLevelLow, scenario.Location, soilProfileProbability,
surfaceLineWithNewHeight);
if (plLines != null)
{
string fullSoilGeometry2DName = (soilProfileProbability.SoilGeometry2DName == null) ? null :
Path.Combine(ProjectDataDirectory, Path.Combine(dike.MapForSoilGeometries2D, soilProfileProbability.SoilGeometry2DName));
double? upliftFactor = GetLowestUpliftFactor(surfaceLineWithNewHeight,
soilProfileProbability.SoilProfile, fullSoilGeometry2DName, plLines, scenario.Location);
upliftSituation.IsUplift = (upliftFactor < upliftCriterion);
}
else
{
upliftSituation.IsUplift = false;
}
scenario.SetStabilityUpliftSituation(soilProfileProbability.SoilProfile,
soilProfileProbability.SoilGeometry2DName, upliftSituation);
}
catch (Exception exception)
{
string errorMessage = String.Format("{0} in location '{1}' scenario '{2}' soilprofile '{3}'",
exception.Message, scenario.Location.Name,
scenario.LocationScenarioID,
soilProfileProbability.SoilGeometryName);
scenario.SetResultMessage(soilProfileProbability.SoilProfile,
soilProfileProbability.SoilGeometry2DName, exception.Message);
var resultRecord = new CsvExportData(
"Error: " + exception.Message,
dike,
damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications[0],
scenario,
soilProfileProbability.SoilProfile,
soilProfileProbability.SoilGeometry2DName,
DamProjectCalculationSpecification.SelectedAnalysisType,
0,
damProjectData.DamProjectCalculationSpecification.SelectedProbabilisticType);
scenario.CalculationResults.Add(resultRecord);
scenario.Errors.Add(errorMessage);
scenario.CalculationResult = CalculationResult.RunFailed;
res = false;
}
}
}
foreach (var error in scenario.Errors)
{
var logMessage = new LogMessage(LogMessageType.Error, null, error);
LogManager.Messages.Add(logMessage);
}
return res;
}
///
/// Determines whether the specified calculation result is Bishop.
///
/// The calculation result.
///
/// true if it is Bishop; otherwise, false.
///
private bool IsBishopResult(CsvExportData calculationResult)
{
return ((calculationResult.DamFailureMechanismeCalculation.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) &&
(calculationResult.DamFailureMechanismeCalculation.FailureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.Bishop));
}
///
/// Determines whether the specified calculation result is UpliftVan.
///
/// The calculation result.
///
/// true if it is UpliftVan; otherwise, false.
///
private bool IsUpliftVanResult(CsvExportData calculationResult)
{
return ((calculationResult.DamFailureMechanismeCalculation.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) &&
(calculationResult.DamFailureMechanismeCalculation.FailureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.UpliftVan));
}
///
/// Create new results depending on Uplift
///
///
private void PostprocessForStabilityUpliftVanBishop(ref List> allCalculationResults)
{
var normativeCalculationResults = new List();
var bishopCalculationResults = new List();
var upliftVanCalculationResults = new List();
// First collect all Bishop and Uplift calculations
foreach (var calculationResults in allCalculationResults)
{
if (calculationResults.Count > 0)
{
foreach (var calculationResult in calculationResults)
{
if (IsBishopResult(calculationResult))
{
bishopCalculationResults.Add(calculationResult);
}
if (IsUpliftVanResult(calculationResult))
{
upliftVanCalculationResults.Add(calculationResult);
}
}
}
}
if ((bishopCalculationResults.Any()) && (upliftVanCalculationResults.Any()))
{
var bishopLiftvancalculation = bishopCalculationResults[0].DamFailureMechanismeCalculation.Clone();
bishopLiftvancalculation.FailureMechanismeParamatersMStab.MStabParameters.Model = MStabModelType.BishopUpliftVan;
foreach (var bishopCalculationRecord in bishopCalculationResults)
{
CsvExportData liftVanCalculationResult = (from calculationResult in upliftVanCalculationResults
where calculationResult.LocationName.Equals(bishopCalculationRecord.LocationName) &&
calculationResult.ScenarioName.Equals(bishopCalculationRecord.ScenarioName) &&
calculationResult.StabilityProfileName.Equals(bishopCalculationRecord.StabilityProfileName)
select calculationResult).ToList().FirstOrDefault();
CsvExportData normativeCalculationResult = SelectStabilityNormativeResult(bishopCalculationRecord, liftVanCalculationResult,
bishopCalculationRecord.AnalysisType, bishopCalculationRecord.ProbabilisticType);
// Clone this result, to make sure the original won't be changed
normativeCalculationResult = (CsvExportData) normativeCalculationResult.Clone();
normativeCalculationResult.DamFailureMechanismeCalculation = bishopLiftvancalculation;
normativeCalculationResults.Add(normativeCalculationResult);
// Add the normative result also to the scenario
normativeCalculationResult.Scenario.CalculationResults.Add(normativeCalculationResult);
}
allCalculationResults.Add(normativeCalculationResults);
}
}
///
/// Select which result is the norm for stability Bishop/UpliftVan calculation
///
///
///
///
private CsvExportData SelectStabilityNormativeResult(CsvExportData bishopCalculationRecord, CsvExportData liftVanCalculationResult, AnalysisType analysisType, ProbabilisticType probabilisticType)
{
switch (analysisType)
{
case AnalysisType.NoAdaption:
switch (probabilisticType)
{
case ProbabilisticType.Deterministic:
return SelectStabilityNormativeResultDeterministicNormal(liftVanCalculationResult, bishopCalculationRecord);
case ProbabilisticType.Probabilistic:
case ProbabilisticType.ProbabilisticFragility:
return SelectStabilityNormativeResultProbabilisticNormal(liftVanCalculationResult, bishopCalculationRecord);
default:
throw new ArgumentOutOfRangeException("probabilisticType");
}
case AnalysisType.AdaptNWO:
case AnalysisType.AdaptGeometry:
switch (probabilisticType)
{
case ProbabilisticType.Deterministic:
return SelectStabilityNormativeResultDeterministicDesign(liftVanCalculationResult, bishopCalculationRecord);
case ProbabilisticType.Probabilistic:
case ProbabilisticType.ProbabilisticFragility:
return SelectStabilityNormativeResultProbabilisticDesign(liftVanCalculationResult, bishopCalculationRecord);
default:
throw new ArgumentOutOfRangeException("probabilisticType");
}
default:
throw new ArgumentOutOfRangeException("analysisType");
}
}
///
/// Select which result is the norm for stability Bishop/UpliftVan normal deterministic calculation
///
///
///
///
private CsvExportData SelectStabilityNormativeResultDeterministicNormal(CsvExportData liftVanCalculationResult, CsvExportData bishopCalculationRecord)
{
if ((liftVanCalculationResult != null) && (liftVanCalculationResult.StabilitySafetyFactor.HasValue))
{
if ((bishopCalculationRecord != null) && (bishopCalculationRecord.StabilitySafetyFactor.HasValue))
{
return (liftVanCalculationResult.StabilitySafetyFactor.Value < bishopCalculationRecord.StabilitySafetyFactor.Value
? liftVanCalculationResult
: bishopCalculationRecord);
}
else
{
return liftVanCalculationResult;
}
}
else
{
return bishopCalculationRecord;
}
}
///
/// Select which result is the norm for stability Bishop/UpliftVan design probabilistic calculation
///
///
///
///
private CsvExportData SelectStabilityNormativeResultProbabilisticDesign(CsvExportData liftVanCalculationResult, CsvExportData bishopCalculationRecord)
{
throw new ApplicationException("Not implemented yet");
}
///
/// Select which result is the norm for stability Bishop/UpliftVan design deterministic calculation
///
///
///
///
private CsvExportData SelectStabilityNormativeResultDeterministicDesign(CsvExportData liftVanCalculationResult, CsvExportData bishopCalculationRecord)
{
if ((liftVanCalculationResult != null) && (liftVanCalculationResult.StabilitySafetyFactor.HasValue))
{
if ((bishopCalculationRecord != null) && (bishopCalculationRecord.StabilitySafetyFactor.HasValue))
{
bool dla = liftVanCalculationResult.DikeLength.HasValue;
dla = dla && bishopCalculationRecord.DikeLength.HasValue;
if (dla && (Math.Abs(liftVanCalculationResult.DikeLength.Value - bishopCalculationRecord.DikeLength.Value) < GeometryPoint.Precision))
{
return (liftVanCalculationResult.StabilitySafetyFactor <
bishopCalculationRecord.StabilitySafetyFactor
? liftVanCalculationResult
: bishopCalculationRecord);
}
else
{
return (liftVanCalculationResult.DikeLength > bishopCalculationRecord.DikeLength
? liftVanCalculationResult
: bishopCalculationRecord);
}
}
else
{
return liftVanCalculationResult;
}
}
else
{
return bishopCalculationRecord;
}
}
///
/// Select which result is the norm for stability Bishop/UpliftVan normal probabilistic calculation
///
///
///
///
private CsvExportData SelectStabilityNormativeResultProbabilisticNormal(CsvExportData liftVanCalculationResult, CsvExportData bishopCalculationRecord)
{
throw new ApplicationException("Not implemented yet");
}
///
/// Create PLLines with selected model
///
///
///
///
///
///
/// the created pl lines
private PLLines CreateAllPLLines(out UpliftSituation upliftSituation, double waterLevel, double? waterLevelLow, Location location, SoilGeometryProbability soilProfileProbability, SurfaceLine2 surfaceLine)
{
switch (location.PLLineCreationMethod)
{
case PLLineCreationMethod.ExpertKnowledgeLinearInDike:
case PLLineCreationMethod.ExpertKnowledgeRRD:
case PLLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD:
return CreateAllPLLinesExpertKnowledge(out upliftSituation, waterLevel, waterLevelLow, location, soilProfileProbability, surfaceLine);
case PLLineCreationMethod.DupuitStatic:
string geometryDirectory = DamProject.ProjectWorkingPath;
return CreateAllPLLinesDupuit(out upliftSituation, location, soilProfileProbability, surfaceLine, geometryDirectory, waterLevel);
case PLLineCreationMethod.DupuitDynamic:
throw new DamCalculationException("PL-Line creation with DupuitDynamic not yet implemented");
default:
upliftSituation.Pl3HeadAdjusted = 0;
upliftSituation.Pl3LocationXMinUplift = 0;
upliftSituation.Pl3MinUplift = 0;
upliftSituation.Pl4HeadAdjusted = 0;
upliftSituation.Pl4LocationXMinUplift = 0;
upliftSituation.Pl4MinUplift = 0;
upliftSituation.IsUplift = false; // must be determined later on; just to avoid compiler error
return null;
}
}
///
/// Create PLLines with Dupuit model
///
/// the created pl lines
private PLLines CreateAllPLLinesDupuit(out UpliftSituation upliftSituation, Location location, SoilGeometryProbability soilProfileProbability,
SurfaceLine2 surfaceLine, String geometryDirectory, double waterLevel)
{
var timeSerieIn = new TimeSerie();
timeSerieIn.Entries.Add(new TimeSerieEntry(DateTime.Now, waterLevel));
var plLinesCreatorDupuit = new PLLinesCreatorDupuit
{
Geometry2DData = Geometry2DDataCreator.CreateGeometry2DData(location, soilProfileProbability, surfaceLine, geometryDirectory),
SurfaceLine = location.LocalXZSurfaceLine2,
WaterLevelTimeserie = timeSerieIn,
SoilList = location.SoilList,
PolderLevel = location.PolderLevel,
IsReverseLayerOrder = true
};
upliftSituation.Pl3HeadAdjusted = 0;
upliftSituation.Pl3LocationXMinUplift = 0;
upliftSituation.Pl3MinUplift = 0;
upliftSituation.Pl4HeadAdjusted = 0;
upliftSituation.Pl4LocationXMinUplift = 0;
upliftSituation.Pl4MinUplift = 0;
upliftSituation.IsUplift = false; // must be determined later on; just to avoid compiler error
plLinesCreatorDupuit.CreateAllPlLines();
return null;
}
///
/// Create PLLines with expert knowledge
///
///
///
///
///
///
/// the created pl lines
private PLLines CreateAllPLLinesExpertKnowledge(out UpliftSituation upliftSituation, double waterLevel,
double? waterLevelLow, Location location, SoilGeometryProbability soilProfileProbability,
SurfaceLine2 surfaceLine)
{
var plLinesCreator = new PLLinesCreator();
// Determine geometry type
SoilGeometryType soilGeometryType = soilProfileProbability.SoilGeometryType;
string mapForSoilGeometries2D = location.MapForSoilGeometries2D;
SoilProfile1D soilProfile = soilProfileProbability.SoilProfile;
string soilGeometry2DName = soilProfileProbability.SoilGeometry2DName;
if ((soilProfileProbability.SoilGeometry2DName != null) && (mapForSoilGeometries2D != null))
{
soilGeometry2DName = Path.Combine(mapForSoilGeometries2D, soilGeometry2DName);
soilGeometry2DName = Path.Combine(ProjectDataDirectory, soilGeometry2DName);
}
plLinesCreator.WaterLevelRiverHigh = waterLevel;
plLinesCreator.WaterLevelRiverLow = waterLevelLow;
plLinesCreator.IsUseLowWaterLevel = (damProjectData.DamProjectCalculationSpecification.CurrentSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityOutside);
plLinesCreator.SurfaceLine = surfaceLine;
plLinesCreator.WaterLevelPolder = location.PolderLevel;
plLinesCreator.HeadInPLLine2 = location.HeadPL2;
plLinesCreator.HeadInPLLine3 = location.HeadPl3;
plLinesCreator.HeadInPLLine4 = location.HeadPl4;
plLinesCreator.ModelParametersForPLLines = location.CreateModelParametersForPLLines();
plLinesCreator.SoilProfile = soilProfile;
plLinesCreator.SoilGeometry2DName = soilGeometry2DName;
plLinesCreator.SoilGeometryType = soilGeometryType;
plLinesCreator.GaugePLLines = location.GaugePLLines;
plLinesCreator.Gauges = location.Gauges;
plLinesCreator.GaugeMissVal = location.GaugeMissVal;
plLinesCreator.IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true; // for stability this must set to true
plLinesCreator.SoilBaseDB = location.SoilbaseDB;
plLinesCreator.SoilList = location.SoilList;
plLinesCreator.DikeEmbankmentMaterial = location.SoilList.GetSoilByName(location.DikeEmbankmentMaterial);
plLinesCreator.PlLineOffsetBelowDikeTopAtRiver = location.PlLineOffsetBelowDikeTopAtRiver;
plLinesCreator.PlLineOffsetBelowDikeTopAtPolder = location.PlLineOffsetBelowDikeTopAtPolder;
plLinesCreator.PlLineOffsetBelowShoulderBaseInside = location.PlLineOffsetBelowShoulderBaseInside;
plLinesCreator.PlLineOffsetBelowDikeToeAtPolder = location.PlLineOffsetBelowDikeToeAtPolder;
plLinesCreator.PlLineOffsetBelowDikeCrestMiddle = location.PlLineOffsetBelowDikeCrestMiddle;
plLinesCreator.PlLineOffsetFactorBelowShoulderCrest = location.PlLineOffsetFactorBelowShoulderCrest;
plLinesCreator.UsePlLineOffsetBelowDikeCrestMiddle = location.UsePlLineOffsetBelowDikeCrestMiddle;
plLinesCreator.UsePlLineOffsetFactorBelowShoulderCrest = location.UsePlLineOffsetFactorBelowShoulderCrest;
plLinesCreator.XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin;
PLLines plLines = plLinesCreator.CreateAllPLLines(location);
upliftSituation.Pl3HeadAdjusted = plLinesCreator.Pl3HeadAdjusted;
upliftSituation.Pl3LocationXMinUplift = plLinesCreator.Pl3LocationXMinUplift;
upliftSituation.Pl3MinUplift = plLinesCreator.Pl3MinUplift;
upliftSituation.Pl4HeadAdjusted = plLinesCreator.Pl4HeadAdjusted;
upliftSituation.Pl4LocationXMinUplift = plLinesCreator.Pl4LocationXMinUplift;
upliftSituation.Pl4MinUplift = plLinesCreator.Pl4MinUplift;
upliftSituation.IsUplift = false; // must be determined later on; just to avoid compiler error
return plLines;
}
}
}