using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Xml.Serialization; using Deltares.AssessmentMechanism; using Deltares.DeltaModel; using Deltares.Geotechnics; using Deltares.Geotechnics.Mechanisms; using Deltares.Geotechnics.Soils; using Deltares.Geotechnics.SurfaceLines; using Deltares.Geotechnics.WaternetCreator; using Deltares.Mathematics; using Deltares.Probabilistic; using Deltares.Standard; using Deltares.Standard.Attributes; using Deltares.Standard.EventPublisher; using Deltares.Standard.Language; using Deltares.Standard.Reflection; using Deltares.Standard.Units; using Deltares.Standard.Validation; namespace Deltares.Stability { public enum StabilityMethod { Bishop, Spencer, UpliftVan, SpencerUpliftVan } /// /// Macro stability info for calculations (used in Ringtoets) /// [XmlOldName("Deltares.Stability.RingtoetsStabilityDikeLocationInfo")] [Mechanism(Mechanism.Stability)] public class StabilityDikeLocationInfo : DikeLocationInfo { private readonly StabilityScenarioManager scenarioManager; private readonly UniformLoad uniformLoad; private bool adjustPl3And4ForUplift = true; private PhreaticAdaptionType nwoPhreaticAdaption = PhreaticAdaptionType.None; private PiezometricHeads piezometricHeads = new PiezometricHeads(); private PlLineCreationMethod plLineCreationMethod = PlLineCreationMethod.RingtoetsWti2017; private double safetyFactor = double.NaN; private double safetyFactorCorrected = double.NaN; private bool settingCurrentScenario; private StabilitySettings settings = new StabilitySettings(); private double slopeDampingPiezometricHeightPolderSide; private StabilityModel stabilityModel; private bool updatingTrafficLoadData; private bool useWaterLevelPolder; public StabilityDikeLocationInfo() { IsCombinedModel = false; stabilityModel = new StabilityModel { CalculationModel = CalculationModel.RTO, PreciseGA = false, ModelOption = ModelOptions.Spencer, SearchAlgorithm = SearchAlgorithm.GeneticAndLevenbergMarquardt, MoveGrid = false, GridOrientation = GridOrientation.Inwards, AutoGenerateGeneticSpencer = true }; stabilityModel.SlipPlaneConstraints.SlipPlaneMinDepth = 2.0; stabilityModel.SoilProfile.Dispose(); stabilityModel.SoilProfile = SoilSurfaceProfile; stabilityModel.Location.PenetrationLength = 0.0; stabilityModel.Location.PiezometricHeads = piezometricHeads; stabilityModel.Location.WaternetCreationMode = WaternetCreationMode.CreateWaternet; stabilityModel.Location.AdjustPl3And4ForUplift = true; stabilityModel.Location.PlLineCreationMethod = PlLineCreationMethod.RingtoetsWti2017; stabilityModel.SlipCircle.Auto = true; stabilityModel.LevenbergMarquardtOptions.DriftGrant = 0.005; uniformLoad = new UniformLoad { Magnitude = 13.3 }; stabilityModel.UniformLoads.Add(uniformLoad); stabilityModel.SlipPlanes.Add(new SlipPlane()); stabilityModel.GeneticAlgorithmOptions = new GeneticAlgorithmOptions { EliteCount = 2, CrossOverScatterFraction = 0, CrossOverSinglePointFraction = 0.4, //CrossOverDoublePointFraction = 0.6, // is set as result of setting CrossOverScatterFraction & CrossOverSinglePointFraction MutationRate = 0.1, MutationJumpFraction = 0.05, //MutationInverseFraction = 0.1, // is set as result of setting MutationJumpFraction & MutationCreepFraction MutationCreepFraction = 0.85, MutationCreepReduction = 0.05, }; stabilityModel.MultiplicationFactorsCPhiForUpliftList.Add(new MultiplicationFactorOnCPhiForUplift { UpliftFactor = 0, MultiplicationFactor = 0 }); scenarioManager = new StabilityScenarioManager(this); DataEventPublisher.OnAfterChange += DataEventPublisher_OnAfterChange; DataEventPublisher.OnDataListModified += DataEventPublisher_OnDataListModified; } public StabilityDikeLocationInfo(DikeLocation dikeLocation, StabilitySettings settings) : this() { DikeLocation = dikeLocation; SurfaceLine = dikeLocation.SurfaceLine; if (settings != null) { this.settings = settings; ApplySettings(); } } /// /// Set of piezometric heads (Pl1 - Pl4 and damping factors). /// [Browsable(false)] [Validate] public virtual PiezometricHeads PiezometricHeads { get { return piezometricHeads; } set { if (value != null) { this.SetAndNotify2(out piezometricHeads, value, dli => dli.PiezometricHeads); stabilityModel.Location.PiezometricHeads = value; } } } /// /// Waternet input parameters. /// /// When is null. [Browsable(false)] [Validate] public Location Location { get { return stabilityModel.Location; } } public PlLineCreationMethod PLLineCreationMethod { get { return plLineCreationMethod; } set { DataEventPublisher.BeforeChange(this, "PLLineCreationMethod"); plLineCreationMethod = value; DataEventPublisher.AfterChange(this, "PLLineCreationMethod"); } } public PhreaticAdaptionType NWOPhreaticAdaption { get { return nwoPhreaticAdaption; } set { DataEventPublisher.BeforeChange(this, "NWOPhreaticAdaption"); nwoPhreaticAdaption = value; DataEventPublisher.AfterChange(this, "NWOPhreaticAdaption"); } } public bool AdjustPl3And4ForUplift { get { return adjustPl3And4ForUplift; } set { DataEventPublisher.BeforeChange(this, "AdjustPl3And4ForUplift"); adjustPl3And4ForUplift = value; DataEventPublisher.AfterChange(this, "AdjustPl3And4ForUplift"); } } public bool UseWaterLevelPolder { get { return useWaterLevelPolder; } set { DataEventPublisher.BeforeChange(this, "UseWaterLevelPolder"); useWaterLevelPolder = value; DataEventPublisher.AfterChange(this, "UseWaterLevelPolder"); } } [Unit(UnitType.None)] [Format("F3")] [Label("Damping Polderside")] public double SlopeDampingPiezometricHeightPolderSide { get { return slopeDampingPiezometricHeightPolderSide; } set { DataEventPublisher.BeforeChange(this, "SlopeDampingPiezometricHeightPolderSide"); slopeDampingPiezometricHeightPolderSide = value; DataEventPublisher.AfterChange(this, "SlopeDampingPiezometricHeightPolderSide"); } } public GeneticAlgorithmOptions GeneticAlgorithmOptions { get { return stabilityModel.GeneticAlgorithmOptions; } set { DataEventPublisher.BeforeChange(this, "GeneticAlgorithmOptions"); stabilityModel.GeneticAlgorithmOptions = value; DataEventPublisher.AfterChange(this, "GeneticAlgorithmOptions"); } } public bool PreciseGeneticAlgorithm { get { return stabilityModel.PreciseGA; } set { DataEventPublisher.BeforeChange(this, "PreciseGeneticAlgorithm"); stabilityModel.PreciseGA = value; DataEventPublisher.AfterChange(this, "PreciseGeneticAlgorithm"); } } public bool MoveGrid { get { return stabilityModel.MoveGrid; } set { DataEventPublisher.BeforeChange(this, "MoveGrid"); stabilityModel.MoveGrid = value; DataEventPublisher.AfterChange(this, "MoveGrid"); } } [Unit(UnitType.Pressure)] [Format("F1")] [Label("Traffic Load")] public double TrafficLoad { get { return uniformLoad.Magnitude; } set { DataEventPublisher.BeforeChange(this, "TrafficLoad"); uniformLoad.Magnitude = value; DataEventPublisher.AfterChange(this, "TrafficLoad"); } } public GridOrientation GridOrientation { get { return stabilityModel.GridOrientation; } set { DataEventPublisher.BeforeChange(this, "GridOrientation"); stabilityModel.GridOrientation = value; DataEventPublisher.AfterChange(this, "GridOrientation"); } } [Format("F2")] [Unit(UnitType.Length)] public double MinimumCircleDepth { get { return stabilityModel.SlipPlaneConstraints.SlipPlaneMinDepth; } set { DataEventPublisher.BeforeChange(this, "MinimumCircleDepth"); stabilityModel.SlipPlaneConstraints.SlipPlaneMinDepth = value; DataEventPublisher.AfterChange(this, "MinimumCircleDepth"); } } public double ToleratedError { get { return stabilityModel.LevenbergMarquardtOptions.DriftGrant; } set { DataEventPublisher.BeforeChange(this, "ToleratedError"); stabilityModel.LevenbergMarquardtOptions.DriftGrant = value; DataEventPublisher.AfterChange(this, "ToleratedError"); } } /// /// Configuration settings for stability calculation. /// [Browsable(false)] [Validate] public StabilityModel StabilityModel { get { return stabilityModel; } set { DataEventPublisher.BeforeChange(this, sdli => sdli.StabilityModel); stabilityModel = value; DataEventPublisher.AfterChange(this, sdli => sdli.StabilityModel); } } public void UpdateStabilityModel(StabilityModel aStabilityModel) { DataEventPublisher.BeforeChange(this, sdli => sdli.StabilityModel); if (stabilityModel != null) { stabilityModel.Dispose(); } stabilityModel = aStabilityModel; if (SoilSurfaceProfile != null) { stabilityModel.SoilProfile = SoilSurfaceProfile; } if (SoilSurfaceProfile2D != null) { stabilityModel.SoilProfile = SoilSurfaceProfile2D; } DataEventPublisher.AfterChange(this, sdli => sdli.StabilityModel); } /// /// The factor of safety for macrostability before divided by Model uncertainty. /// [Format("F2")] [Unit(UnitType.None)] [ReadOnly(true)] public double SafetyFactor { set { safetyFactor = value; } get { return safetyFactor; } } /// /// The factor of safety for macrostability after divided by Model uncertainty. /// [Format("F2")] [ReadOnly(true)] public double SafetyFactorCorrected { set { safetyFactorCorrected = value; } get { return safetyFactorCorrected; } } /// /// Whether the result of the assessment makes the dike section acceptable or unsafe for macrostability. /// [ReadOnly(true)] public bool StabilityAcceptable { get; set; } /// /// The text to show if dike section is acceptable for macrostability. /// [ReadOnly(true)] [XmlIgnore] public string StabilityAcceptableResult { get { if (double.IsNaN(SafetyFactorCorrected)) { return string.Empty; } return StabilityAcceptable ? LocalizationManager.GetTranslatedText(this, "Approved") : LocalizationManager.GetTranslatedText(this, "NotApproved"); } } [Browsable(false)] public SlidingCurve SlidingCurve { get { return StabilityModel.MinimumSafetyCurve; } } [Browsable(false)] public Waternet Waternet { get { return StabilityModel.GeotechnicsData.CurrentWaternet; } } public bool UseCustomWaternet { get { return Location.WaternetCreationMode == WaternetCreationMode.CreateWaternet; } set { Location.WaternetCreationMode = value ? WaternetCreationMode.CreateWaternet : WaternetCreationMode.FillInWaternetValues; } } /// /// General settings for stability /// public StabilitySettings Settings { get { return settings; } set { settings = value; } } [XmlIgnore] public StabilityMethod StabilityMethod { get { if (IsCombinedModel) { return StabilityMethod.SpencerUpliftVan; } else { switch (stabilityModel.ModelOption) { case ModelOptions.Bishop: return StabilityMethod.Bishop; case ModelOptions.Spencer: return StabilityMethod.Spencer; case ModelOptions.UpliftVan: return StabilityMethod.UpliftVan; default: throw new NotSupportedException(stabilityModel.ModelOption.ToString()); } } } set { DataEventPublisher.BeforeChange(this, "StabilityMethod"); switch (value) { case StabilityMethod.Bishop: StabilityModel.ModelOption = ModelOptions.Bishop; break; case StabilityMethod.Spencer: StabilityModel.ModelOption = ModelOptions.Spencer; break; case StabilityMethod.UpliftVan: StabilityModel.ModelOption = ModelOptions.UpliftVan; break; case StabilityMethod.SpencerUpliftVan: StabilityModel.ModelOption = ModelOptions.Spencer; break; default: throw new NotSupportedException(value.ToString()); } IsCombinedModel = value == StabilityMethod.SpencerUpliftVan; DataEventPublisher.AfterChange(this, "StabilityMethod"); } } [XmlOmit(false)] public bool IsCombinedModel { get; set; } [XmlIgnore] public ModelOptions ModelOption { get { return StabilityModel.ModelOption; } set { StabilityModel.ModelOption = value; } } [XmlIgnore] public SlipPlanePosition SlipPlanePosition { get { return StabilityModel.SlipPlanePosition; } set { StabilityModel.SlipPlanePosition = value; } } public override DikeLocation DikeLocation { get { return base.DikeLocation; } set { base.DikeLocation = value; UpdateLocation(); } } public override Soil DefaultDikeEmbankmentMaterial { get { return base.DefaultDikeEmbankmentMaterial; } set { bool valueWillChange = !ReferenceEquals(defaultDikeEmbankmentMaterial, value); this.SetAndNotify2(out defaultDikeEmbankmentMaterial, value, x => x.DefaultDikeEmbankmentMaterial); if (valueWillChange) { scenarioManager.UpdateDikeEmbankmentMaterial(value); } } } public override SoilProfile1D SoilProfile { get { return base.SoilProfile; } set { base.SoilProfile = value; if (value != null && StabilityModel != null) { StabilityModel.SoilProfile = SoilSurfaceProfile; } } } public override SoilSurfaceProfile SoilSurfaceProfile { get { return base.SoilSurfaceProfile; } protected set { // Do not dispose instance, due to being alive in StabilityScenarioManager this.SetAndNotify2(out soilSurfaceProfile, value, sdli => sdli.SoilSurfaceProfile); if (value != null && StabilityModel != null) { StabilityModel.SoilProfile = SoilSurfaceProfile; } } } public override SoilProfile2D SoilProfile2D { get { return base.SoilProfile2D; } set { base.SoilProfile2D = value; if (value != null && StabilityModel != null) { StabilityModel.SoilProfile = SoilSurfaceProfile2D; } } } public override SoilSurfaceProfile2D SoilSurfaceProfile2D { get { return base.SoilSurfaceProfile2D; } protected set { // Do not dispose instance, due to being alive in StabilityScenarioManager this.SetAndNotify2(out soilSurfaceProfile2D, value, sdli => sdli.SoilSurfaceProfile2D); if (value != null && StabilityModel != null) { StabilityModel.SoilProfile = SoilSurfaceProfile2D; } } } public override SurfaceLine2 SchematizedSurfaceLine { get { return base.SchematizedSurfaceLine; } set { base.SchematizedSurfaceLine = value; stabilityModel.SurfaceLine2 = value; // Note: additional logic in setter due to uniform load not being serialized UpdateTrafficLoad(); } } public override IList Scenarios { get { if (!DataEventPublisher.IsDataEventPublishStopped && scenarioManager.Scenarios.Count == 0) { InitializeScenarios(); } return scenarioManager.Scenarios; } } public override AssessmentScenario CurrentScenario { get { if (scenarioManager.ActiveScenario == null) { if (!DataEventPublisher.IsDataEventPublishStopped && Scenarios.Count == 0) { InitializeScenarios(); } } return scenarioManager.ActiveScenario; } set { if (scenarioManager.ActiveScenario != value) { DataEventPublisher.BeforeChange(this, dli => dli.CurrentScenario); settingCurrentScenario = true; scenarioManager.ActiveScenario = value; settingCurrentScenario = false; DataEventPublisher.AfterChange(this, dli => dli.CurrentScenario); } } } /// /// Applies to global stability settings to the stability model /// public void ApplySettings() { StabilityModel.SlipPlaneConstraints.CreateZones = Settings.CreateZones; StabilityModel.MaximumSliceWidth = Settings.MaximumSlideWidth; StabilityModel.SlipPlaneConstraints.SlipPlaneMinDepth = Settings.MinimalPlaneDepth; StabilityModel.SlipPlaneConstraints.SlipPlaneMinLength = Settings.MinimalCircleLength; StabilityModel.MaxAllowedAngleBetweenSlices = Settings.MaxAllowedAngleBetweenSlices; StabilityModel.RequiredForcePointsInSlices = Settings.RequiredForcePointsInSlices; StabilityModel.PreconsolidationStressModelFactor = Settings.PreconsolidationStressFactor; StabilityModel.ModelUncertaintyParameterStochast.Assign(Settings.ModelUncertaintyParameterStochast); } [Validate] public IValidationResult[] ValidateScenarios() { return scenarioManager.ValidateScenarioProbabilities() .Concat(scenarioManager.Validate()) .ToArray(); } [Validate] public IValidationResult[] ValidateWaternetCreationPossible() { var result = new List(); //early exit: If waternet shall not be generated, this validation is not necessary if (stabilityModel.Location.WaternetCreationMode != WaternetCreationMode.CreateWaternet) { return result.ToArray(); } if (DikeLocation == null || DikeLocation.SchematizedSurfaceLine == null) { result.Add(new ValidationResult(ValidationResultType.Error, "Er ontbreekt een oppervlakte lijn.")); return result.ToArray(); } var surfaceLine = DikeLocation.SchematizedSurfaceLine; if (!surfaceLine.CharacteristicPoints.Any()) { result.Add(new ValidationResult(ValidationResultType.Error, "Het glijvlak kan niet worden gemaakt omdat de karakteristieke punten ontbreken.")); } if (!StabilityModel.SoilProfile.Surfaces.Any()) { result.Add(new ValidationResult(ValidationResultType.Error, "Het glijvlak kan niet worden gemaakt omdat grondlagen ontbreken.")); } if (StabilityModel.SoilProfile.Surfaces.Any(p => p.Soil == null)) { result.Add(new ValidationResult(ValidationResultType.Error, "Het glijvlak kan niet worden gemaakt omdat sommige grondlagen geen grond-definitie bevatten.")); } if (surfaceLine.CharacteristicPoints.Any() && DikeLocation.AssessmentLevel > surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z) { var message = String.Format( "Het freatisch water niveau moet ten minste éénmaal met de dijk snijden (freatische lijn hoger ({0:F2} m) dan profiellijn ({1:F2}))", DikeLocation.AssessmentLevel, surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z); result.Add(new ValidationResult(ValidationResultType.Error, message)); } if (Location.PlLineCreationMethod == PlLineCreationMethod.ExpertKnowledgeLinearInDike || Location.PlLineCreationMethod == PlLineCreationMethod.ExpertKnowledgeRrd || Location.PlLineCreationMethod == PlLineCreationMethod.RingtoetsWti2017) { //if (this.StabilityModel.SoilProfile.HasAquiferOverCompleteWidth()) } return result.ToArray(); } public override void RevertSurfaceLine() { base.RevertSurfaceLine(); UpdateTrafficLoad(); } /// /// Initializes the dike location for a 2b calculation /// public override void InitializeForCalculation() { StabilityModel.OnlyMinimumSafetyCurve = true; StabilityModel.MinimumSafetyCurve = null; } /// /// Finalizes the dike location from a 2b calculation /// public override void FinalizeFromCalculation() { StabilityModel.OnlyMinimumSafetyCurve = true; } public override void InitializeScenarios() { scenarioManager.InitializeScenarios(); } public override List GetStochasts() { var stochasts = new List(); if (StabilityModel != null && StabilityModel.SoilProfile != null) { foreach (var soil in StabilityModel.SoilProfile.Surfaces.Select(p => p.Soil).Distinct()) { if (soil != null) { stochasts.AddRange(soil.GetStochasts()); } } foreach (var stress in StabilityModel.SoilProfile.PreconsolidationStresses) { if (stress != null) { stochasts.Add(stress.StressStochast); } } stochasts.Add(Settings.ModelUncertaintyParameterStochast); } return stochasts; } /// /// Shows / hides various properties based on selection of other properties /// /// The property /// Visibility indication public override bool IsVisible(string property) { switch (property) { case "ModelOption": return IsCombinedModel; case "SlipPlanePosition": return StabilityModel.ModelOption == ModelOptions.Spencer && (!IsCombinedModel || SlidingCurve != null); case "ToleratedError": return stabilityModel.SearchAlgorithm == SearchAlgorithm.LevenbergMarquardt; case "MoveGrid": return stabilityModel.SearchAlgorithm == SearchAlgorithm.Grid; case "GeneticAlgorithmOptions": return stabilityModel.SearchAlgorithm == SearchAlgorithm.Genetic; default: return base.IsVisible(property); } } /// /// Enables / disables various properties based on selection of other properties /// /// The property /// Enabled indication public override bool IsEnabled(string property) { switch (property) { case "ModelOption": return false; case "SlipPlanePosition": return !IsCombinedModel; case "RequiredMacrostabilitySafetyFactor": return true; case "UseCustomWaternet": return Waternet != null; case "TrafficLoad": return (IsTrafficLoadEnabled()); } return base.IsEnabled(property); } public override void Dispose() { DataEventPublisher.OnAfterChange -= DataEventPublisher_OnAfterChange; DataEventPublisher.OnDataListModified -= DataEventPublisher_OnDataListModified; if (stabilityModel != null) { stabilityModel.Dispose(); } scenarioManager.Dispose(); base.Dispose(); } public override ICollection GetDomain(string property) { if (property == this.GetMemberName(sdli => sdli.ModelOption)) { return new List { ModelOptions.Bishop, ModelOptions.UpliftVan, ModelOptions.Spencer }; } return base.GetDomain(property); } private void DataEventPublisher_OnDataListModified(object sender, PublishEventArgs e) { if (StabilityModel != null && sender == StabilityModel.SoilProfile.PreconsolidationStresses) { DataEventPublisher.AfterChange(this); } } private void DataEventPublisher_OnAfterChange(object sender, PublishEventArgs e) { if (!settingCurrentScenario && ReferenceEquals(sender, scenarioManager) && scenarioManager.GetMemberName(sm => sm.ActiveScenario) == e.Property) { DataEventPublisher.AfterChange(this, sdli => sdli.CurrentScenario); } if (sender == DikeLocation || HasAssessmentLevelUpdatedInOriginal(DikeLocation, sender)) { UpdateLocation(); if (e.Property == StaticReflection.GetMemberName(dl => dl.SchematizedSurfaceLine)) { stabilityModel.SurfaceLine2 = SchematizedSurfaceLine; } } if (DikeLocation != null && sender == PiezometricHeads) { UpdateLocation(); } var characteristicPoint = sender as CharacteristicPoint; if (characteristicPoint != null && stabilityModel.SurfaceLine2 != null && SurfaceLineHasCharacteristicPoint(stabilityModel.SurfaceLine2, characteristicPoint) && (e.Property == "Z" || e.Property == "X")) { if (characteristicPoint.CharacteristicPointType == CharacteristicPointType.TrafficLoadInside || characteristicPoint.CharacteristicPointType == CharacteristicPointType.TrafficLoadOutside) { UpdateTrafficLoad(); } } if (sender == uniformLoad && (e.Property == "XStart" || e.Property == "XEnd")) { UpdateCharacteristicPointsTrafficLoad(); } } private bool SurfaceLineHasCharacteristicPoint(SurfaceLine2 surfaceLine, CharacteristicPoint characteristicPoint) { return ReferenceEquals(characteristicPoint.PointSet, surfaceLine.CharacteristicPoints); } private bool HasAssessmentLevelUpdatedInOriginal(DikeLocation dikeLocation, object sender) { // This is a HACK. // // During Waterlevel assessment calculation we like to synchronize the assessment // levels to this.DikeLocation. However, we cannot seem to determine when this // data is being set on the DikeLocation instances of stability (nor any other failure // mechanism). // We have found the following relationship, which we used to 'detect assessment level updated'. var senderAsDikeSection = sender as DikeCrossSection; var dikeCrossSection = dikeLocation as DikeSection; if (senderAsDikeSection == null || dikeCrossSection == null) { return false; } return ReferenceEquals(dikeCrossSection.RepresentativeDikeCrossSection.OriginalDikeLocation, senderAsDikeSection.OriginalDikeLocation); } private void UpdateLocation() { if (DataEventPublisher.IsDataEventPublishStopped) { return; } //sync during deserialisation if (StabilityModel.Location == null || DikeLocation == null) { return; } Location location = StabilityModel.Location; //Problems with thread safe calls of stability controls and possible missing objects for creating a grid (model listens to location events) DataEventPublisher.InvokeWithoutPublishingEvents(delegate { location.WaterLevelRiver = DikeLocation.AssessmentLevel; location.PiezometricHeads = PiezometricHeads; location.AdjustPl3And4ForUplift = AdjustPl3And4ForUplift; location.NWOPhreaticAdaption = NWOPhreaticAdaption; location.PlLineCreationMethod = PLLineCreationMethod; location.SlopeDampingPiezometricHeightPolderSide = SlopeDampingPiezometricHeightPolderSide; }); } # region Traffic load public void UpdateTrafficLoad() { if (updatingTrafficLoadData) { return; } updatingTrafficLoadData = true; try { uniformLoad.SurfaceLine2 = stabilityModel.SurfaceLine2; uniformLoad.XStart = 0.0; uniformLoad.XEnd = 0.0; if (stabilityModel.SurfaceLine2 != null) { var trafficLoadInside = stabilityModel.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadInside); var trafficLoadOutside = stabilityModel.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadOutside); if (trafficLoadInside != null && !Double.IsNaN(trafficLoadInside.X) && trafficLoadOutside != null && !Double.IsNaN(trafficLoadOutside.X)) { uniformLoad.XStart = Math.Min(trafficLoadInside.X, trafficLoadOutside.X); uniformLoad.XEnd = Math.Max(trafficLoadInside.X, trafficLoadOutside.X); } } } finally { updatingTrafficLoadData = false; } } private bool IsTrafficLoadEnabled() { return DikeLocation != null && DikeLocation.SchematizedSurfaceLine != null && DikeLocation.SchematizedSurfaceLine.IsDefined(CharacteristicPointType.TrafficLoadInside) && DikeLocation.SchematizedSurfaceLine.IsDefined(CharacteristicPointType.TrafficLoadOutside); } private void UpdateCharacteristicPointsTrafficLoad() { if (updatingTrafficLoadData) { return; } updatingTrafficLoadData = true; var trafficLoadInside = stabilityModel.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadInside); var trafficLoadOutside = stabilityModel.SurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadOutside); if (trafficLoadInside != null && trafficLoadOutside != null) { if (trafficLoadInside.X < trafficLoadOutside.X) { trafficLoadInside.X = uniformLoad.XStart; trafficLoadOutside.X = uniformLoad.XEnd; } else { trafficLoadInside.X = uniformLoad.XEnd; trafficLoadOutside.X = uniformLoad.XStart; } } updatingTrafficLoadData = false; } # endregion } }