// 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 System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using Deltares.DamEngine.Calculators.Dikes_Design; using Deltares.DamEngine.Calculators.General; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.Results; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Probabilistic; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Language; using Deltares.DamEngine.Data.Standard.Logging; using Deltares.DamEngine.Data.Standard.Validation; namespace Deltares.DamEngine.Calculators { public class MaximumRedesignIterationsReachedException : Exception { public MaximumRedesignIterationsReachedException() : base("Maximum number of iterations in redesign reached.") { } } /// /// /// public class DamFailureMechanismeCalculator { private const int PipingRedesingMaxIterations = 400; private const double defaultMaxFractionOfDikeHeightForShoulderHeight = 0.67; private const double CMinimumShoulderElevation = 0.5; private const double CMinimumShoulderExtraElevation = 0.05; private const double CMinimumShoulderWidth = 2; private const double CMinimumShoulderExtraWidth = 1; private const double CToleranceShoulderChanges = 0.001; private readonly DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification; private readonly string mstabProgramPath; private readonly ProgramType programType; private readonly string slopeWProgramPath; private AnalysisType analysisType; private List errorMessages = new List(); private int progressSofar; public DamFailureMechanismeCalculator(ProgramType programType, DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification, string mstabProgramPath, string slopeWProgramPath, string mapForSoilGeometries2D) { this.programType = programType; this.damFailureMechanismeCalculationSpecification = damFailureMechanismeCalculationSpecification; this.mstabProgramPath = mstabProgramPath; this.slopeWProgramPath = slopeWProgramPath; MapForSoilGeometries2D = mapForSoilGeometries2D; } public string CalculationBaseDirectory { get; set; } public string MapForSoilGeometries2D { get; set; } public List ErrorMessages { get { return errorMessages; } set { errorMessages = value; } } /// /// Main calculation call /// /// /// public void Calculate(AnalysisType analysisTypeGiven, DesignScenario scenario) { Debug.WriteLine("Location '{0}', scenario '{1}' DamFailureMechanismeCalculator.Calculation", scenario.Location.Name, scenario.LocationScenarioID); analysisType = analysisTypeGiven; switch (analysisType) { case AnalysisType.NoAdaption: CalculateForScenario(scenario); break; case AnalysisType.AdaptGeometry: RedesignSurfaceLinesForAllScenarios(scenario); break; } } /// /// Selects the probabilities for specific failure mechanism. /// /// Type of the failure mechanism system. /// The soil profile probabilities. /// public static List SelectProbabilitiesForFailureMechanism(FailureMechanismSystemType failureMechanismSystemType, IList soilProfileProbabilities) { switch (failureMechanismSystemType) { case FailureMechanismSystemType.StabilityInside: case FailureMechanismSystemType.StabilityOutside: case FailureMechanismSystemType.HorizontalBalance: return SelectStabilityProbabilities(soilProfileProbabilities); case FailureMechanismSystemType.Piping: return SelectPipingProbabilities(soilProfileProbabilities); } return null; } /// /// Redesigns the height of the surface line. /// /// Type of the failure mechanism system. /// The scenario. /// The surface line. /// public static SurfaceLine2 RedesignSurfaceLineHeight(FailureMechanismSystemType failureMechanismSystemType, DesignScenario scenario, SurfaceLine2 surfaceLine) { double? dikeHeight = surfaceLine.GetDikeHeight(); if (dikeHeight.HasValue) { if (scenario.DikeTableHeight > dikeHeight.Value) { var surfaceLineHeightAdapter = new SurfaceLineHeightAdapter(surfaceLine, scenario.Location); SurfaceLine2 adaptedSurfaceLine = surfaceLineHeightAdapter.ConstructNewSurfaceLine(scenario.DikeTableHeight ?? surfaceLine.GetDefaultDikeTableHeight() ?? 0); if (adaptedSurfaceLine != null) { var validationError = adaptedSurfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); if (validationError != null) { throw new SurfaceLineException(validationError.Text); } surfaceLine = adaptedSurfaceLine; foreach (var soilProfileProbability in scenario.Location.Segment.SoilProfileProbabilities) { if (soilProfileProbability.SegmentFailureMechanismType == failureMechanismSystemType || soilProfileProbability.SegmentFailureMechanismType == null) { scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, surfaceLine); } } } } } return surfaceLine; } /// /// Cleanup directory where the piping project files are created /// public static void ClearPipingCalculationBaseDirectory() { string pipingBaseDirectory = GetPipingCalculationBaseDirectory(); if (Directory.Exists(pipingBaseDirectory)) { Directory.Delete(pipingBaseDirectory, true); } } private void CalculateForScenario(DesignScenario scenario) { // switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType) // { // case FailureMechanismSystemType.StabilityInside: // case FailureMechanismSystemType.StabilityOutside: // CalculateStabilityForScenario(scenario, 0); // break; // case FailureMechanismSystemType.Piping: // CalculatePipingForScenario(scenario); // break; // } } /// /// /// /// /// /// /// /// /// // private double? CalculatePipingReliabilityIndexForSurface(Scenario scenario, SurfaceLine2 newSurfaceLine, PipingCalculator pipingCalculator, SoilGeometryProbability soilProfileProbability, // ProbabilisticStruct waterLevel) // { // double? betaloc; // if (newSurfaceLine != null) // { // betaloc = pipingCalculator.CalculateReliabilityIndex(scenario.Location, newSurfaceLine, soilProfileProbability.SoilProfile1D, waterLevel); // } // else // { // betaloc = pipingCalculator.CalculateReliabilityIndex(scenario.Location, scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName), soilProfileProbability.SoilProfile1D, waterLevel); // } // return betaloc; // } /// /// /// /// /// /// // private void CalculatePipingForScenario(Scenario scenario) // { // var waterLevelProbabilistic = new ProbabilisticStruct(0.0, 0.01, (int) DistributionType.LogNormal, false); // string pipingCalculationDirectory = GetPipingCalculationBaseDirectory(); // try // { // var validSoilProfileProbabilities = SelectPipingProbabilities(scenario.Location.Segment.SoilProfileProbabilities); // if (validSoilProfileProbabilities.Count == 0) // { // throw new DamFailureMechanismeCalculatorException(String.Format("No piping profiles to calcutate for location {0}", scenario.Location.Name)); // } // foreach (var soilProfileProbability in validSoilProfileProbabilities) // { // try // { // var pipingResults = new PipingResults(); // foreach (PipingModelType pipingCalculationType in Enum.GetValues(typeof(PipingModelType))) // { // var pipingProbabilisticParameters = new PipingProbabilisticParameters(scenario.Location.LayerHeightDistribution, scenario.Location.LayerHeightDeviation); // PipingCalculator pipingCalculator = pipingCalculatorFactory(scenario.Location, scenario.Location.CreateModelParametersForPLLines(), // pipingCalculationType, // scenario.GetUpliftCriterionPiping(scenario.Location.ModelFactors.UpliftCriterionPiping), // scenario.GetRequiredSafetyFactorPiping(scenario.Location.ModelFactors.RequiredSafetyFactorPiping), // pipingProbabilisticParameters); // pipingCalculator.PipingCalculationDirectory = pipingCalculationDirectory; // double? safetyFactor = null; // double? pipingExitPointX = null; // double? upliftFactor = null; // double? heaveFactor = null; // try // { // // safetyFactor = pipingCalculator.CalculatePipingFactor( // scenario.Location, // scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName), // soilProfileProbability.SoilProfile1D, // scenario.RiverLevel); // if (pipingCalculator.UpliftLocationAndResult != null) // { // pipingExitPointX = pipingCalculator.UpliftLocationAndResult.X; // upliftFactor = pipingCalculator.UpliftLocationAndResult.UpliftFactor; // heaveFactor = pipingCalculator.HeaveFactor; // } // break; // // } // catch (Exception exception) // { // throw new DamFailureMechanismeCalculatorException(exception.Message); // } // // if (pipingCalculationType == PipingModelType.SellmeijerVnk) // { // scenario.SetSafetyFactorPiping(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, safetyFactor); // } // pipingResults.CalculationName = pipingCalculator.FilenameCalculation; // pipingResults.CalculationSubDir = @"PipingCalculation\\"; // pipingResults.PipingExitPointX = pipingExitPointX; // pipingResults.UpliftFactor = upliftFactor; // pipingResults.HeaveFactor = heaveFactor; // switch (pipingCalculationType) // { // case PipingModelType.Bligh: // pipingResults.BlighHCritical = pipingCalculator.HCritical; // pipingResults.BlighPipingFactor = safetyFactor; // break; // case PipingModelType.SellmeijerVnk: // pipingResults.SellmeijerVnkHCritical = pipingCalculator.HCritical; // pipingResults.SellmeijerVnkPipingFactor = safetyFactor; // break; // case PipingModelType.Sellmeijer2Forces: // pipingResults.Sellmeijer2ForcesHCritical = pipingCalculator.HCritical; // pipingResults.Sellmeijer2ForcesPipingFactor = safetyFactor; // break; // case PipingModelType.Sellmeijer4Forces: // pipingResults.Sellmeijer4ForcesHCritical = pipingCalculator.HCritical; // pipingResults.Sellmeijer4ForcesPipingFactor = safetyFactor; // break; // case PipingModelType.Wti2017: // pipingResults.Wti2017HCritical = pipingCalculator.HCritical; // pipingResults.Wti2017PipingFactor = safetyFactor; // break; // } // } // scenario.SetPipingResults(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, pipingResults); // } // catch (DamFailureMechanismeCalculatorException calculatorException) // { // string errorMessage = "FAIL: " + calculatorException.Message; // Exception innerException = calculatorException.InnerException; // while (innerException != null) // { // errorMessage = errorMessage + ";" + innerException.Message; // innerException = innerException.InnerException; // } // scenario.SetResultMessage(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, errorMessage); // // calculatorException.Scenario = scenario; // throw calculatorException; // } // } // } // catch (Exception exception) // { // scenario.Errors.Add(exception.Message); // Exception innerException = exception.InnerException; // while (innerException != null) // { // scenario.Errors.Add(innerException.Message); // innerException = innerException.InnerException; // } // } // } /// /// Selects the soilProfileProbabilities for piping. /// /// The soil profile probabilities. /// private static List SelectPipingProbabilities(IList soilProfileProbabilities) { var validSoilProfileProbabilities = new List(soilProfileProbabilities.Where( p => ((p.SegmentFailureMechanismType == FailureMechanismSystemType.Piping) || (p.SegmentFailureMechanismType == null)))); return validSoilProfileProbabilities; } /// /// Selects the soilProfileProbabilities for stability. /// /// The soil profile probabilities. /// private static List SelectStabilityProbabilities(IList soilProfileProbabilities) { var validSoilProfileProbabilities = new List(soilProfileProbabilities.Where( p => ((p.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityInside) || (p.SegmentFailureMechanismType == FailureMechanismSystemType.StabilityOutside) || (p.SegmentFailureMechanismType == null)))); return validSoilProfileProbabilities; } /// /// Selects the flowslide probabilities. /// /// The soil profile probabilities. /// private static List SelectFlowSlideProbabilities(IList soilProfileProbabilities) { // For now use the stability probabilities return SelectStabilityProbabilities(soilProfileProbabilities); } /// /// Consistency check to be performed before stability calculation /// /// private void ConsistencyCheckStability(DesignScenario scenario) { ConsistencyCheckStabilityPerScenario(scenario); } private void ConsistencyCheckStabilityPerScenario(DesignScenario scenario) { // If outward stability calculation then low waterlevel is required if (damFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.GridPosition == MStabGridPosition.Left) { if (!scenario.RiverLevelLow.HasValue) { throw new DamFailureMechanismeCalculatorException(String.Format( "Location {0} scenario {1} has no low waterlevel defined, which is required for outward stability calculation (grid at left).", scenario.Location.Name, scenario.LocationScenarioID)); } } } /// /// Stability calculation /// /// // private void CalculateStabilityForScenario(Scenario scenario, int iter) // { // try // { // ConsistencyCheckStability(scenario); // Location location = scenario.Location; // var modelParametersForPLLines = new ModelParametersForPLLines // { // PenetrationLength = location.PenetrationLength, // DampingFactorPL3 = location.DampingFactorPL3, // DampingFactorPL4 = location.DampingFactorPL4, // PLLineCreationMethod = location.PLLineCreationMethod // }; // var requiredSafetyFactorStabilityInnerSlope = scenario.RequiredSafetyFactorStabilityInnerSlope ?? // location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope; // using (var stabilityCalculator = // new StabilityCalculator( // damFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab, // programType, // modelParametersForPLLines, // location.TrafficLoad, // location.MinimalCircleDepth, // requiredSafetyFactorStabilityInnerSlope.Value, // mstabProgramPath, slopeWProgramPath, // location.GaugePLLines, // location.Gauges, // location.SoilbaseDB, // location.SoilList, // ProbabilisticType) // { // SelectedStabilityKernelType = damFailureMechanismeCalculationSpecification.StabilityKernelType // }) // { // //stabilityCalculator.CalculationBaseDirectory = this.CalculationBaseDirectory; // var validSoilProfileProbabilities = SelectStabilityProbabilities(scenario.Location.Segment.SoilProfileProbabilities); // if (validSoilProfileProbabilities.Count == 0) // { // throw new DamFailureMechanismeCalculatorException(String.Format("No stability profiles to calcutate for location {0}", scenario.Location.Name)); // } // int errorCount = 0; // var scenarioErrorMessages = new List(); // foreach (var soilProfileProbability in validSoilProfileProbabilities) // { // try // { // UpliftSituation? upliftSituation = scenario.GetStabilityUpliftSituation(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName); // // The calculation for UpliftVan will only will done if there is Uplift // if (IsCalculationRequired(upliftSituation)) // { // stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile1D, GetFullSoilGeometry2DName(soilProfileProbability.StiFileName), iter); // MStabResults? mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName); // } // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName, // scenario.Location.SurfaceLine2); // } // catch (DamFailureMechanismeCalculatorException calculatorException) // { // string errorMessage = "FAIL: " + calculatorException.Message; // Exception innerException = calculatorException.InnerException; // while (innerException != null) // { // errorMessage = errorMessage + ";" + innerException.Message; // innerException = innerException.InnerException; // } // scenario.SetResultMessage(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName, errorMessage); // // calculatorException.Scenario = scenario; // errorCount++; // scenarioErrorMessages.Add(errorMessage); // } // } // if (errorCount > 0) // { // string errorMessage = String.Format("{0} calculation error(s) in location {1} scenario {2}", // errorCount, location.Name, scenario.LocationScenarioID); // foreach (var scenarioErrorMessage in scenarioErrorMessages) // { // errorMessage = String.Format("{0}; {1}", errorMessage, scenarioErrorMessage); // } // var calculatorException = new DamFailureMechanismeCalculatorException(errorMessage) // { // Scenario = scenario // }; // throw calculatorException; // } // } // } // catch (Exception exception) // { // scenario.Errors.Add(exception.Message); // Exception innerException = exception.InnerException; // while (innerException != null) // { // scenario.Errors.Add(innerException.Message); // innerException = innerException.InnerException; // } // throw; // } // } /// /// Check if calculation should be done /// (In case of UpliftVan and no uplift this is not the case) /// /// The uplift situation. /// /// true if [is calculation required] ; otherwise, false. /// private bool IsCalculationRequired(UpliftSituation? upliftSituation) { bool isUplift = upliftSituation.HasValue && upliftSituation.Value.IsUplift; bool isSkipCalculation = (!isUplift && damFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.IsStabilityCheckOnUplift && (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside) && (damFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.Model == MStabModelType.UpliftVan)); return !isSkipCalculation; } // private void CalculateScenario(Scenario scenario, int iter) // { // switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType) // { // case FailureMechanismSystemType.StabilityInside: // case FailureMechanismSystemType.StabilityOutside: // ConsistencyCheckStabilityPerScenario(scenario); // CalculateStabilityForScenario(scenario, iter); // break; // // case FailureMechanismSystemType.Piping: // CalculatePipingForScenario(scenario); // break; // } // } /// /// /// /// private void RedesignSurfaceLinesForAllScenarios(DesignScenario scenario) { // try // { // RedesignSurfaceLine(scenario); // } // catch (Exception exception) // { // scenario.Errors.Add(exception.Message); // Exception innerException = exception.InnerException; // while (innerException != null) // { // scenario.Errors.Add(innerException.Message); // innerException = innerException.InnerException; // } // } } /// /// /// /// /// // private void RedesignSurfaceLine(Scenario scenario) // { // try // { // if (scenario.Location != null) // { // SurfaceLine2 surfaceLine = scenario.Location.LocalXZSurfaceLine2.FullDeepClone(); //TODO: I really have no clue this object should be in a using clause or not... :( // if (scenario.Location.RedesignDikeHeight) // { // // Dike height adaptation // // var redesignedSurfaceLine = RedesignSurfaceLineHeight(damFailureMechanismeCalculationSpecification.FailureMechanismSystemType, // scenario, surfaceLine); // var validationError = redesignedSurfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); // if (validationError != null) // { // redesignedSurfaceLine.Dispose(); // throw new SurfaceLineException(validationError.Text); // } // // // No error, so replace clone with redesigned surfaceline // surfaceLine.Dispose(); // surfaceLine = redesignedSurfaceLine; // } // // if (scenario.Location.RedesignDikeShoulder) // { // // Shoulder and slope adaption // double? safetyFactor = null; // switch (damFailureMechanismeCalculationSpecification.FailureMechanismSystemType) // { // case FailureMechanismSystemType.StabilityInside: // case FailureMechanismSystemType.StabilityOutside: // safetyFactor = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope; // RedesignSurfaceLineStabilityInside(scenario, safetyFactor); // break; // // case FailureMechanismSystemType.Piping: // safetyFactor = scenario.ModelFactors.RequiredSafetyFactorPiping; // RedesignSurfaceLinePipingShoulder(damFailureMechanismeCalculationSpecification.PipingModelType, // scenario, ref safetyFactor, ref surfaceLine); // break; // } // } // } // } // catch (DamFailureMechanismeCalculatorException calculatorException) // { // calculatorException.Scenario = scenario; // throw; // } // } /// /// /// /// /// /// /// // private void RedesignSurfaceLinePipingShoulder(PipingModelType pipingModelType, Scenario scenario, ref double? safetyFactor, ref SurfaceLine2 surfaceLine) // { // var modelParametersForPLLines = new ModelParametersForPLLines // { // PenetrationLength = scenario.Location.PenetrationLength, // DampingFactorPL3 = scenario.Location.DampingFactorPL3, // DampingFactorPL4 = scenario.Location.DampingFactorPL4, // PLLineCreationMethod = scenario.Location.PLLineCreationMethod // }; // // var pipingProbabilisticParameters = new PipingProbabilisticParameters(scenario.Location.LayerHeightDistribution, // scenario.Location.LayerHeightDeviation); // var pipingUpliftCriterion = scenario.GetUpliftCriterionPiping(scenario.Location.ModelFactors.UpliftCriterionPiping); // if (pipingUpliftCriterion <= 0) // { // throw new DamFailureMechanismeCalculatorException(String.Format("Invalid piping uplift criterion {0} for location {1} scenario {2}", // pipingUpliftCriterion, scenario.Location.Name, scenario.LocationScenarioID)); // } // // var requiredSafetyFactorPiping = 0.0; // if (scenario.RequiredSafetyFactorPiping != null) // { // requiredSafetyFactorPiping = scenario.RequiredSafetyFactorPiping.Value; // } // if (safetyFactor != null) // { // requiredSafetyFactorPiping = safetyFactor.Value; // } // if (requiredSafetyFactorPiping <= 0) // { // throw new DamFailureMechanismeCalculatorException(String.Format("Invalid required safetyfactor piping {0} for location {1} scenario {2}", // requiredSafetyFactorPiping, scenario.Location.Name, scenario.LocationScenarioID)); // } // PipingCalculator pipingCalculator = pipingCalculatorFactory(scenario.Location, modelParametersForPLLines, pipingModelType, // pipingUpliftCriterion, // requiredSafetyFactorPiping, // pipingProbabilisticParameters); // // var validSoilProfileProbabilities = SelectPipingProbabilities(scenario.Location.Segment.SoilProfileProbabilities); // if (validSoilProfileProbabilities.Count == 0) // { // throw new DamFailureMechanismeCalculatorException(String.Format("No piping profiles to calcutate for location {0}", scenario.Location.Name)); // } // foreach (var soilProfileProbability in validSoilProfileProbabilities) // { // try // { // SurfaceLine2 newSurfaceLine = surfaceLine.FullDeepClone(); // var newCandidate = DetermineNewSafeSurfaceLinePipingDeterministic(scenario, soilProfileProbability, pipingCalculator, newSurfaceLine, ref safetyFactor); // if (!ReferenceEquals(newSurfaceLine, newCandidate)) // { // newSurfaceLine.Dispose(); // newSurfaceLine = newCandidate; // } // // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, newSurfaceLine); // scenario.SetSafetyFactorPiping(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, safetyFactor); // PipingResults pipingResults = GetPipingResults(safetyFactor, pipingModelType, pipingCalculator); // scenario.SetPipingResults(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, pipingResults); // // scenario.SetResultMessage(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, "Succes"); // } // catch (Exception exception) // { // string errorMessage = String.Format("Location '{0}', Soilprofile '{1}': {2}", // scenario.Location.Name, soilProfileProbability.SoilGeometryName, exception.Message); // PipingResults pipingResults = GetPipingResults(-1, pipingModelType, pipingCalculator); // scenario.SetPipingResults(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, pipingResults); // scenario.SetSafetyFactorPiping(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, -1); // scenario.Errors.Add("FAIL: " + errorMessage); // scenario.SetResultMessage(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, "FAIL: " + errorMessage); // } // } // } // private PipingResults GetPipingResults(double? safetyFactor, PipingModelType pipingModelType, PipingCalculator pipingCalculator) // { // var pipingResults = new PipingResults(); // switch (pipingModelType) // { // case PipingModelType.Bligh: // pipingResults.BlighHCritical = pipingCalculator.HCritical; // pipingResults.BlighPipingFactor = safetyFactor; // break; // case PipingModelType.SellmeijerVnk: // pipingResults.SellmeijerVnkHCritical = pipingCalculator.HCritical; // pipingResults.SellmeijerVnkPipingFactor = safetyFactor; // break; // case PipingModelType.Sellmeijer2Forces: // pipingResults.Sellmeijer2ForcesHCritical = pipingCalculator.HCritical; // pipingResults.Sellmeijer2ForcesPipingFactor = safetyFactor; // break; // case PipingModelType.Sellmeijer4Forces: // pipingResults.Sellmeijer4ForcesHCritical = pipingCalculator.HCritical; // pipingResults.Sellmeijer4ForcesPipingFactor = safetyFactor; // break; // case PipingModelType.Wti2017: // pipingResults.Wti2017HCritical = pipingCalculator.HCritical; // pipingResults.Wti2017PipingFactor = safetyFactor; // break; // } // return pipingResults; // } /// /// Ensures that the points on the surface line are never more than cDiff (0.5) apart. /// /// /// private IEnumerable GetCheckedSurfaceLine(IEnumerable originalLine) { const double cDiff = 0.5; var newLine = new List(); double X = originalLine.First().X; foreach (var point in originalLine) { while (point.X > X + cDiff) { var newPoint = new GeometryPoint(point) { X = X + cDiff }; if (newPoint.X > newLine.Last().X) { newPoint.Z = newLine.Last().Z + ((newPoint.X - newLine.Last().X)/(point.X - newLine.Last().X))* (point.Z - newLine.Last().Z); newLine.Add(newPoint); } X = newPoint.X; } newLine.Add(point); } return newLine; } // private SurfaceLine2 DetermineNewSafeSurfaceLinePipingDeterministic(Scenario scenario, SoilGeometryProbability soilProfileProbability, PipingCalculator pipingCalculator, SurfaceLine2 surfaceLine, ref double? safetyFactor) // { // double orgShoulderLength = surfaceLine.DetermineShoulderWidth(); // double orgShoulderHeight = surfaceLine.DetermineShoulderHeight(); // double desiredShoulderLength = orgShoulderLength; // double desiredShoulderHeight = orgShoulderHeight; // double oldDesiredShoulderLength = orgShoulderLength; // double oldDesiredShoulderHeight = orgShoulderHeight; // // GeometryPoint startSurfacePoint = surfaceLine.GetDikeToeInward(); // // IEnumerable relevantSurfacePointsList = from GeometryPoint point in surfaceLine.Geometry.Points // where point.X >= startSurfacePoint.X // orderby point.X ascending // select point; // relevantSurfacePointsList = GetCheckedSurfaceLine(relevantSurfacePointsList); // int pointCount = 0; // foreach (var point in relevantSurfacePointsList) // { // pointCount++; // // Determine calculation filename to output piping calculation file // //pipingCalculator.PipingCalculationDirectory = GetPipingCalculationBaseDirectory(); // //string fileNameCalculation =String.Format("Calc({0})_Loc({1})_Pro({2})_Pnt({3}))", // // pipingCalculator.CalculationModelIdentifier, scenario.Location.Name, soilProfileProbability.SoilProfile1D.Name, pointCount.ToString("d4")); ; // //pipingCalculator.FilenameCalculation = Path.Combine(pipingCalculator.PipingCalculationDirectory, fileNameCalculation); // // // Calculate the piping design at the given point. This returns the required adaption (berm length and height) if any. // var pipingDesign = pipingCalculator.CalculateDesignAtPoint(scenario.Location, surfaceLine, // soilProfileProbability.SoilProfile1D, // scenario.RiverLevel, point); // if (pipingDesign != null) // { // // Piping is an issue so adapt the surfaceline for it // desiredShoulderLength = pipingDesign.PipingLengthFromToe; // desiredShoulderLength = Math.Max(desiredShoulderLength, oldDesiredShoulderLength); // oldDesiredShoulderLength = desiredShoulderLength; // // shoulder height is height above surfacelevel!! // desiredShoulderHeight = pipingDesign.ShoulderHeightFromToe; // desiredShoulderHeight = Math.Max(desiredShoulderHeight, oldDesiredShoulderHeight); // oldDesiredShoulderHeight = desiredShoulderHeight; // } // } // if (desiredShoulderLength > 0) // { // desiredShoulderLength = Math.Max(desiredShoulderLength, CMinimumShoulderWidth); // } // if (desiredShoulderLength > 0) // { // desiredShoulderHeight = Math.Max(desiredShoulderHeight, CMinimumShoulderElevation); // } // bool isNewShoulderSameAsOriginal = ((Math.Abs(desiredShoulderLength - orgShoulderLength) < CToleranceShoulderChanges) && // (Math.Abs(desiredShoulderHeight - orgShoulderHeight) < CToleranceShoulderChanges)); // if (isNewShoulderSameAsOriginal) // { // return surfaceLine; // } // else // { // // Adapt the surfaceline for the finally required shoulder dimensions. // double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, 1.0); // no limit to height of shoulder // var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, scenario.Location); // surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; // SurfaceLine2 newSurfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(desiredShoulderLength, desiredShoulderHeight, true); // // safetyFactor = pipingCalculator.CalculatePipingFactor(scenario.Location, newSurfaceLine, soilProfileProbability.SoilProfile1D, scenario.RiverLevel); // if (safetyFactor < scenario.RequiredSafetyFactorPiping) // { // throw new DamFailureMechanismeCalculatorException("Deterministic Design: Piping is not safe yet."); // } // return newSurfaceLine; // } // } /// /// Create the initial geometry to be used to determine layers for embankment for design /// /// /// /// /// /// /// // private void CreateInitialGeometry(Scenario scenario, StabilityCalculator stabilityCalculator, SoilGeometryProbability soilProfileProbability, SurfaceLine2 surfaceLine, out String initialgeometryFile) // { // const int IterationIndex = -1; // // initialgeometryFile = StabilityCalculator.DetermineCalculationFilename(scenario.Location.Name, scenario.LocationScenarioID, soilProfileProbability.SoilGeometryName, IterationIndex); // initialgeometryFile = initialgeometryFile + stabilityCalculator.GetFilenameExtension(); // initialgeometryFile = Path.Combine(stabilityCalculator.GetStabilityCalculationDirectory(), initialgeometryFile); // double riverLevel = 0.5*(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).Z + // surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z); // string soilgeometry2DFilename = null; // if (soilProfileProbability.StiFileName != null) // { // soilgeometry2DFilename = // Path.GetFullPath(Path.Combine(DamProject.ProjectMap, Path.Combine(scenario.Location.MapForSoilGeometries2D, soilProfileProbability.StiFileName))); // } // XDocument mstabXML = stabilityCalculator.CreateMStabXmlDoc(initialgeometryFile, scenario, soilProfileProbability.SoilProfile1D, // soilgeometry2DFilename, riverLevel, null, surfaceLine); // mstabXML.Save(initialgeometryFile + ".xml"); // var stabilityServiceAgent = new StabilityServiceAgent(); // stabilityServiceAgent.CreateProjectFile(mstabXML.ToString()); // if (!File.Exists(initialgeometryFile)) // { // throw new DamFailureMechanismeCalculatorException("Initial geometry file (sti) is not created."); // } // } /// /// Redesigns the surface line for mechanism stability inside. /// /// The scenario. /// The safety factor. // private void RedesignSurfaceLineStabilityInside(Scenario scenario, double? requiredSafetyFactor) // { // Location location = scenario.Location; // var modelParametersForPLLines = new ModelParametersForPLLines // { // PenetrationLength = location.PenetrationLength, // DampingFactorPL3 = location.DampingFactorPL3, // DampingFactorPL4 = location.DampingFactorPL4, // PLLineCreationMethod = location.PLLineCreationMethod // }; // using (var stabilityCalculator = // new StabilityCalculator(damFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab, // programType, // modelParametersForPLLines, // location.TrafficLoad, // location.MinimalCircleDepth, // requiredSafetyFactor.Value, // mstabProgramPath, // slopeWProgramPath, // location.GaugePLLines, // location.Gauges, // location.SoilbaseDB, // location.SoilList, // ProbabilisticType) // { // SelectedStabilityKernelType = damFailureMechanismeCalculationSpecification.StabilityKernelType // }) // { // var validSoilProfileProbabilities = SelectStabilityProbabilities(scenario.Location.Segment.SoilProfileProbabilities); // if (validSoilProfileProbabilities.Count == 0) // { // throw new DamFailureMechanismeCalculatorException(String.Format("No stability profiles to calcutate for location {0}", scenario.Location.Name)); // } // foreach (var soilProfileProbability in validSoilProfileProbabilities) // { // // The calculation for UpliftVan will only will done if there is Uplift // UpliftSituation? upliftSituation = scenario.GetStabilityUpliftSituation(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName); // if (IsCalculationRequired(upliftSituation)) // { // switch (scenario.Location.StabilityDesignMethod) // { // // Bij WTIkernel is het soilprofile2D nog null in de soilProfileProbability en daarom gat Adapt Geometry fout. //// nagaan bij classic Delphi of dat daar ook leeg is. Daarnaast is het probleem groter. Je moet denk ik de geometrie geheel regenereren NADAT de surfaceline //// is aangepast. Dan moet de soilprofile2D goed gezet worden (en ook de sti + naam sti!?!?!?! uitzoeken!) op de nieuwe 2Dgeom. En die moet goed in de kernel terecht komen. //// Dus dat kan nog niet hier want de nieuwe surfaceline is nog niet bekend. Gebruik maken van de surf2dprof combiner!! // case StabilityDesignMethod.OptimizedSlopeAndShoulderAdaption: // { // RedesignCombinedSlopeAdaptionAndShoulderAdaption(scenario, stabilityCalculator, soilProfileProbability); // break; // } // case StabilityDesignMethod.SlopeAdaptionBeforeShoulderAdaption: // { // RedesignFirstSlopeAdaptionThenShoulderAdaption(scenario, stabilityCalculator, soilProfileProbability); // break; // } // } // } // } // } // } /// /// Redesign for Stability: /// Dependent on the exit point of the stability circle. /// If the exit point is in the slope, the slope will be adapted. /// If the exit point is not in the slope, a shoulder will be made, /// or if the shoulder exists, the shoulder will be enlarged. /// /// /// /// /// // private void RedesignCombinedSlopeAdaptionAndShoulderAdaption(Scenario scenario, StabilityCalculator stabilityCalculator, // SoilGeometryProbability soilProfileProbability) // { // Location location = scenario.Location; // double requiredSafetyFactor = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? // scenario.Location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope.Value; // const int maxRedesignIterations = 200; // int iterationIndex = 1; // string previousFilename; // SurfaceLine2 orgSurfaceLine = scenario.Location.LocalXZSurfaceLine2; // // // Create the file with the initial geometry to be used to determine which layers have to be defined as dike embankment material // CreateInitialGeometry(scenario, stabilityCalculator, soilProfileProbability, orgSurfaceLine, out previousFilename); // SurfaceLine2 surfaceLine = scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName).FullDeepClone(); // // var mstabDesignEmbankment = new MStabDesignEmbankment // { // EmbankmentMaterialname = location.DikeEmbankmentMaterial, // PreviousGeometry2DFilename = previousFilename // }; // // try // { // bool isRedesignRequired; // double? exitPointXCoordinate; // scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); // stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile1D, // GetFullSoilGeometry2DName(soilProfileProbability.StiFileName), // iterationIndex, mstabDesignEmbankment); // mstabDesignEmbankment.PreviousGeometry2DFilename = stabilityCalculator.StabilityProjectFilename; // mstabDesignEmbankment.EmbankmentMaterialname = location.ShoulderEmbankmentMaterial; // MStabResults? mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName); // double? safetyFactor = mStabResults.Value.zone1.safetyFactor; // isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor); // exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; // // if (!isRedesignRequired && surfaceLine != null) // { // // Set redesigned surfaceline to original, so in case no redesign is needed, the original surfaceline will be returned // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName, surfaceLine); // } // else // { // double maxFractionOfDikeHeightForShoulderHeight = scenario.Location.UseNewMaxHeightShoulderAsFraction ? // scenario.Location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; // double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, maxFractionOfDikeHeightForShoulderHeight); // while (isRedesignRequired && surfaceLine != null) // { // iterationIndex++; // if (iterationIndex >= maxRedesignIterations) // { // throw new MaximumRedesignIterationsReachedException(); // } // // GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); // if (exitPointXCoordinate > limitPointForShoulderDesign.X) // { // // If exit point of circle is after the limitPointForShoulderDesign then enlarge the shoulder // // // Determine new width and height for shoulder // double shoulderHeight; // double shoulderWidth; // DetermineNewShoulderWidthAndHeight(scenario.Location.StabilityShoulderGrowDeltaX, // scenario.Location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, out shoulderHeight, out shoulderWidth); // // // Create new shoulder // var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, scenario.Location); // surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; // surfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); // // var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); // if (validationError != null) // { // throw new SurfaceLineException(validationError.Text); // } // // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, surfaceLine); // } // else // { // // If exit point of circle is in the slope (inward) of the dike or the top of the shoulder then adapt slope // var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, scenario.Location); // surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLine(scenario.Location.StabilitySlopeAdaptionDeltaX); // // var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); // if (validationError != null) // { // throw new SurfaceLineException(validationError.Text); // } // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName, surfaceLine); // } // // scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); // stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile1D, // GetFullSoilGeometry2DName(soilProfileProbability.StiFileName), // iterationIndex, mstabDesignEmbankment); // // mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName); // safetyFactor = mStabResults.Value.zone1.safetyFactor; // isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor); // exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; // } // } // scenario.SetResultMessage(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, "Succes"); // } // catch (Exception exception) // { // string errorMessage = "FAIL: " + exception.Message; // Exception innerException = exception.InnerException; // while (innerException != null) // { // errorMessage = errorMessage + ";" + innerException.Message; // innerException = innerException.InnerException; // } // scenario.SetResultMessage(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, errorMessage); // // Add message to log too for output tab. // errorMessage = scenario.Location.Name + ", scenario " + scenario.LocationScenarioID + ", " + soilProfileProbability.SoilGeometryName + " " + errorMessage; // stabilityCalculator.ErrorMessages.Add(new LogMessage(LogMessageType.Error, this, errorMessage)); // scenario.CalculationResult = CalculationResult.RunFailed; // // Redesign not succesful, so no redesigned surfaceline will be returned // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, null); // } // foreach (var errorMessage in stabilityCalculator.ErrorMessages) // { // errorMessages.Add(errorMessage); // } // } /// /// Determines the new height and width of the shoulder width /// /// The shoulder grow delta X. /// The shoulder grow slope. /// The surface line. /// The limit point for shoulder design. /// New height of the shoulder. /// New width of the shoulder. // private static void DetermineNewShoulderWidthAndHeight(double shoulderGrowDeltaX, double shoulderGrowSlope, // SurfaceLine2 surfaceLine, GeometryPoint limitPointForShoulderDesign, out double shoulderHeight, out double shoulderWidth) // { // // Determine new shoulderpoint // var newShoulderPoint = new GeometryPoint() // { // X = limitPointForShoulderDesign.X + shoulderGrowDeltaX, // Z = limitPointForShoulderDesign.Z + shoulderGrowDeltaX*shoulderGrowSlope // }; // // // Determine new shoulder width and height // shoulderWidth = surfaceLine.DetermineShoulderLengthForGivenShoulderTopInside(newShoulderPoint); // shoulderHeight = newShoulderPoint.Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; // } /// /// Redesign for Stability: /// - first do slope adaption (until required safety is reached) /// * slope adaption is done in a range between startCoTangent and endCoTangent in steps of stepCoTangent /// * and while the exit point of the slipcircle is in the slope (so currentCoTangent could be larger than endCoTangent /// - than (if required safety is not reached) do shoulder adaption /// Note: Use same slope for shoulder as for dike. /// /// /// /// /// // private void RedesignFirstSlopeAdaptionThenShoulderAdaption(Scenario scenario, StabilityCalculator stabilityCalculator, // SoilGeometryProbability soilProfileProbability) // { // Location location = scenario.Location; // double requiredSafetyFactor = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? // scenario.Location.ModelFactors.RequiredSafetyFactorStabilityInnerSlope.Value; // const int maxRedesignIterations = 200; // int iterationIndex = 1; // string previousFilename; // SurfaceLine2 orgSurfaceLine = scenario.Location.LocalXZSurfaceLine2; // // // Create the file with the initial geometry to be used to determine which layers have to be defined as dike embankment material // CreateInitialGeometry(scenario, stabilityCalculator, soilProfileProbability, orgSurfaceLine, out previousFilename); // SurfaceLine2 surfaceLine = scenario.GetMostRecentSurfaceLine(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName).FullDeepClone(); // // var mstabDesignEmbankment = new MStabDesignEmbankment // { // EmbankmentMaterialname = location.DikeEmbankmentMaterial, // PreviousGeometry2DFilename = previousFilename // }; // // try // { // bool isRedesignRequired; // double? exitPointXCoordinate; // scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); // stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile1D, // GetFullSoilGeometry2DName(soilProfileProbability.StiFileName), // iterationIndex, mstabDesignEmbankment); // mstabDesignEmbankment.PreviousGeometry2DFilename = stabilityCalculator.StabilityProjectFilename; // mstabDesignEmbankment.EmbankmentMaterialname = location.ShoulderEmbankmentMaterial; // MStabResults? mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName); // double? safetyFactor = mStabResults.Value.zone1.safetyFactor; // isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor); // exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; // // if (!isRedesignRequired && surfaceLine != null) // { // // Set redesigned surfaceline to original, so in case no redesign is needed, the original surfaceline will be returned // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName, surfaceLine); // } // else // { // double maxFractionOfDikeHeightForShoulderHeight = scenario.Location.UseNewMaxHeightShoulderAsFraction ? // scenario.Location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; // double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, maxFractionOfDikeHeightForShoulderHeight); // while (isRedesignRequired && surfaceLine != null) // { // // First slope adaption // double startCoTangent = location.SlopeAdaptionStartCotangent; // double endCoTangent = location.SlopeAdaptionEndCotangent; // double stepCoTangent = location.SlopeAdaptionStepCotangent; // var orgCotangent = surfaceLine.GetCotangentOfInnerSlope(); // double coTangent = startCoTangent; // double currentCoTangent = orgCotangent; // // // Find out for which cotangent we want to start designing // while (coTangent <= orgCotangent) // { // coTangent += stepCoTangent; // } // // // Design for slope adaption // GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); // while (isRedesignRequired && (coTangent < endCoTangent)) // { // iterationIndex++; // if (iterationIndex >= maxRedesignIterations) // { // throw new MaximumRedesignIterationsReachedException(); // } // var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, scenario.Location); // // The parameter for ConstructNewSurfaceLineBySlope is the tangent of the slope, so use reciproce value // surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLineBySlope(1/coTangent); // currentCoTangent = coTangent; // // var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); // if (validationError != null) // { // throw new SurfaceLineException(validationError.Text); // } // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName, surfaceLine); // // // Recalculate new surfaceline // scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); // stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile1D, // GetFullSoilGeometry2DName(soilProfileProbability.StiFileName), // iterationIndex, mstabDesignEmbankment); // mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile1D, // soilProfileProbability.StiFileName); // safetyFactor = mStabResults.Value.zone1.safetyFactor; // exitPointXCoordinate = mStabResults.Value.zone1.circleSurfacePointRightXCoordinate; // isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor); // limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); // // coTangent += stepCoTangent; // } // // // Then shoulder adaption // while (isRedesignRequired && surfaceLine != null) // { // iterationIndex++; // if (iterationIndex >= maxRedesignIterations) // { // throw new MaximumRedesignIterationsReachedException(); // } // // // Determine new width and height for shoulder // double shoulderHeight; // double shoulderWidth; // DetermineNewShoulderWidthAndHeight(scenario.Location.StabilityShoulderGrowDeltaX, // scenario.Location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, out shoulderHeight, out shoulderWidth); // // // Create new shoulder // var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, scenario.Location); // surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; // surfaceLineShoulderAdapter.SlopeOfNewShoulder = currentCoTangent; // surfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); // // var validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); // if (validationError != null) // { // throw new SurfaceLineException(validationError.Text); // } // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, surfaceLine); // // // Recalculate new surfaceline // scenario.Location.AlignBoundaryPointsOfPL1LineWithAdaptedSurfaceLine(surfaceLine); // stabilityCalculator.Calculate(scenario, soilProfileProbability.SoilProfile1D, // GetFullSoilGeometry2DName(soilProfileProbability.StiFileName), // iterationIndex, mstabDesignEmbankment); // mStabResults = scenario.GetMStabResults(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName); // safetyFactor = mStabResults.Value.zone1.safetyFactor; // isRedesignRequired = IsRedesignRequired(safetyFactor, requiredSafetyFactor); // limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); // } // } // } // scenario.SetResultMessage(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, "Succes"); // } // catch (Exception exception) // { // string errorMessage = "FAIL: " + exception.Message; // Exception innerException = exception.InnerException; // while (innerException != null) // { // errorMessage = errorMessage + ";" + innerException.Message; // innerException = innerException.InnerException; // } // scenario.SetResultMessage(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, errorMessage); // scenario.CalculationResult = CalculationResult.RunFailed; // // Redesign not succesful, so no redesigned surfaceline will be returned // scenario.SetRedesignedSurfaceLine(soilProfileProbability.SoilProfile1D, soilProfileProbability.StiFileName, null); // } // foreach (var errorMessage in stabilityCalculator.ErrorMessages) // { // errorMessages.Add(errorMessage); // } // } /// /// Check if a stability redesign is required /// /// /// /// private bool IsRedesignRequired(double? safetyFactor, double requiredSafetyFactor) { return safetyFactor < requiredSafetyFactor; } /// /// /// /// /// // private PipingCalculator pipingCalculatorFactory(Location location, ModelParametersForPLLines modelParametersForPLLines, PipingModelType pipingModelType, double upliftCriterion, double requiredSafetyFactorPiping, PipingProbabilisticParameters? pipingProbabilisticParameters) // { // switch (pipingModelType) // { // case PipingModelType.Bligh: // return new PipingCalculatorBligh(modelParametersForPLLines, // requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); // case PipingModelType.SellmeijerVnk: // PipingProbabilisticParameters? actualPipingProbabilisticParameters = null; // if ((ProbabilisticType == ProbabilisticType.Probabilistic) || (ProbabilisticType == ProbabilisticType.ProbabilisticFragility)) // { // actualPipingProbabilisticParameters = pipingProbabilisticParameters; // } // return new PipingCalculatorSellmeijer(modelParametersForPLLines, // requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, actualPipingProbabilisticParameters, upliftCriterion); // case PipingModelType.Sellmeijer2Forces: // return new PipingCalculatorSellmeijer2Forces(modelParametersForPLLines, // requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); // case PipingModelType.Sellmeijer4Forces: // return new PipingCalculatorSellmeijer4Forces(modelParametersForPLLines, // requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); // case PipingModelType.Wti2017: // return new PipingCalculatorWti2017(modelParametersForPLLines, // requiredSafetyFactorPiping, location.GaugePLLines, location.Gauges, upliftCriterion); // } // return null; // } /// /// /// /// /// // private string GetFullSoilGeometry2DName(string soilGeometry2DName) // { // if (soilGeometry2DName == null) // { // return null; // } // else // { // string fullSoilGeometry2DName = Path.Combine(DamProjectData.ProjectMap, Path.Combine(MapForSoilGeometries2D, soilGeometry2DName)); // return fullSoilGeometry2DName; // } // } /// /// Get the directory where to create the piping project files /// /// private static string GetPipingCalculationBaseDirectory() { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "PipingCalculation\\"); } /// /// Calculates the maximum level for the shoulder. /// /// The surface line. /// The fraction of dike height to determine maximimum shoulder height. /// private double CalculateMaximumShoulderLevel(SurfaceLine2 surfaceLine, double maxFractionOfDikeHeightForShoulderHeight) { var top = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z; var bottom = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; if (top - bottom <= 0) { throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineShoulderAdapterMaxShoulderHeightError")); } double maxHeight = Math.Abs((top - bottom)*maxFractionOfDikeHeightForShoulderHeight); return bottom + maxHeight; } } }