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
}
}