// 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; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General.Results; using Deltares.DamEngine.Data.General.SchematizationFactor; using Deltares.DamEngine.Data.General.Sensors; using Deltares.DamEngine.Data.RWScenarios; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Language; using Deltares.DamEngine.Data.Standard.Validation; namespace Deltares.DamEngine.Data.General { public class DamProjectData { public readonly double MissValStabilitySafetyFactor = -1.0; // ##Bka Waterboard eruit werken en vanaf nu max 1 dike! private string description = ""; private IList segments; private Dike dike; private DamProjectCalculationSpecification damProjectCalculationSpecification; private DikeJob dikeJob; private DamProjectType damProjectType = DamProjectType.Operational; private ProgramType programType = ProgramType.MStab; private List jobs = new List(); private SchematizationFactorData schematizationFactorData = new SchematizationFactorData(); private List calculations = null; // will be created and initialized in property private List designCalculations = null; private List schematizationFactors = null; private SensorData sensorData; /// /// Constructor /// public DamProjectData() { dikeJob = null; damProjectCalculationSpecification = new DamProjectCalculationSpecification(); dike = new Dike(); segments = new List(); } public static string ProjectMap = ""; public static string ProjectWorkingPath { get; set; } public static string MStabExePath { get; set; } public static string SlopeWExePath { get; set; } public virtual string Name { get { return String.Format(LocalizationManager.GetTranslatedText(this, "WaterBoard")); } } public virtual string Description { get { return description; } set { description = value; } } public virtual IList Segments { get { return segments; } set { segments = value; } } /// /// Gets the dike. /// Is a helper property to be able to show the soil table. When more Dikes than one are allowed, /// this has to become a "real" property set by the onselectionchanged event. /// /// /// The selected dike. /// public Dike Dike { get { return dike; } set { dike = value; } } /// /// calculation specification for the project /// /// Composite relationship [Validate] public DamProjectCalculationSpecification DamProjectCalculationSpecification { get { return damProjectCalculationSpecification; } set { damProjectCalculationSpecification = value; } } public virtual DamJob DikeJob { get { if (dikeJob == null) { dikeJob = new DikeJob(dike); foreach (Location location in dike.Locations) { LocationJob locationJob = new LocationJob(location); dikeJob.Jobs.Add(locationJob); } } return dikeJob; } set { dikeJob = value as DikeJob; } } public virtual DamProjectType DamProjectType { get { return damProjectType; } set { bool modified = damProjectType != value; damProjectType = value; Location.DamProjectType = value; DamFailureMechanismeCalculationSpecification.DamProjectType = value; if (modified) { LocationJob.DamProjectType = damProjectType; } } } public List Calculations { get { if (calculations == null) { calculations = new List(); this.UpdateCalculations(); } return calculations; } } public void UpdateCalculations() { if (calculations != null) { calculations.Clear(); foreach (LocationJob locationJob in this.LocationJobs) { if (locationJob.HasRWScenarioResults) { foreach (RWScenarioResult locationResult in locationJob.RWScenarioResults) { calculations.AddRange(locationResult.RWScenarioProfileResults); } } } } } private List CreateScenarioListForDeletion() { List scenarios = new List(); ; List locations = this.LocationJobs.Select(x => x.Location).ToList(); foreach (Location location in locations) { if (location.Scenarios != null) { scenarios.AddRange(location.Scenarios); } } return scenarios; } private List CreateScenarioListForCalculation() { List scenarios = new List(); ; List locations = this.SelectedLocationJobs.Select(x => x.Location).ToList(); foreach (Location location in locations) { if (location.Scenarios != null) { scenarios.AddRange(location.Scenarios); } } return scenarios; } /// /// Updates the design calculations. /// public void UpdateDesignCalculations() { if (designCalculations == null) { designCalculations = new List(); } else { designCalculations.Clear(); } var scenarios = CreateScenarioListForCalculation(); foreach (DesignScenario scenario in scenarios) { if (scenario.CalculationResults != null && scenario.CalculationResults.Count > 0) { designCalculations.AddRange(scenario.CalculationResults); } } } public List DesignCalculations { get { if (designCalculations == null) { this.UpdateDesignCalculations(); } return designCalculations; } } public List SchematizationFactors { get { if (schematizationFactors == null) { schematizationFactors = new List(); this.UpdateSchematizationFactors(); } return schematizationFactors; } } public void UpdateSchematizationFactors() { if (schematizationFactors != null) { schematizationFactors.Clear(); foreach (LocationJob locationJob in this.LocationJobs) { if (locationJob.HasSchematizationFactorResults) { foreach ( var rwSchematizationFactorResult in locationJob.LocationResult.SchematizationFactorsResult.SchematizationFactorResults) { schematizationFactors.Add(rwSchematizationFactorResult); } } } } } public SchematizationFactorData SchematizationFactorData { get { return schematizationFactorData; } set { schematizationFactorData = value; } } public CalculationResult Validate() { try { dike.Validate(); return CalculationResult.Succeeded; } catch { return CalculationResult.InvalidInputData; } } public LocationJob GetLocationJob(Location location) { foreach (LocationJob locationJob in this.LocationJobs) { if (locationJob.Location == location) { return locationJob; } } return null; } public List LocationJobs { get { if (jobs.Count == 0) { foreach (LocationJob locationJob in dikeJob.Jobs) { jobs.Add(locationJob); } } return jobs; } } public LocationJob GetFirstLocationJobWithDesignResults() { foreach (LocationJob locationJob in this.LocationJobs) { if (locationJob.HasScenarioResults) { return locationJob; } } return null; } public LocationJob GetFirstLocationJobWithAssesmentResults() { foreach (LocationJob locationJob in this.LocationJobs) { if (locationJob.HasRWScenarioResults) { return locationJob; } } return null; } public LocationJob GetFirstLocationJobWithCalamityResults() { foreach (LocationJob locationJob in this.LocationJobs) { if (locationJob.HasLocationResults) { return locationJob; } } return null; } [Validate] public List SelectedLocationJobs { get { List selectedLocationJobs = new List(); foreach (LocationJob locationJob in this.LocationJobs) { if (locationJob.Run.HasValue && locationJob.Run.Value) { selectedLocationJobs.Add(locationJob); } } return selectedLocationJobs; } } [Validate] public ValidationResult[] ValidateEnoughLocationJobs() { if (this.SelectedLocationJobs.Count == 0) { return new ValidationResult[] { new ValidationResult(ValidationResultType.Error, LocalizationManager.GetTranslatedText(this, "NoLocationsSelected"), this) }; } else { return new ValidationResult[0]; } } public ProgramType ProgramType { // For now, only MStab (= default value) allowed so ReadOnly. Add setter when needed. get { return programType; } } /// /// Gets or sets the sensor data. /// /// /// The sensor data. /// public SensorData SensorData { get { return sensorData; } set { sensorData = value; } } public EvaluationJob GetEvaluationJob() { EvaluationJob evaluationJob = new EvaluationJob(); evaluationJob.DikeName = dike.Name; foreach (LocationJob locationJob in this.LocationJobs) { if (locationJob.Run != null && locationJob.Run.Value) { if (dike.Locations.Contains(locationJob.Location)) { dike.UpdateLocation(locationJob.Location); break; } evaluationJob.Locations.Add(locationJob.Location); } } return evaluationJob; } /// /// Ensures the proper zone safety factors are available for all locations. /// public void EnsureProperZoneSafetyFactors() { if (dike != null) { foreach (var location in dike.Locations) { location.EnsureProperZoneSafetyFactors(); } } } public void DeleteResults() { if (dikeJob != null && dikeJob.Jobs != null) { dikeJob.Jobs.Clear(); } dikeJob = null; if (jobs != null) { jobs.Clear(); } if (calculations != null) { calculations.Clear(); } if (schematizationFactors != null) { schematizationFactors.Clear(); } // Delete calculationresults in scenarios var scenarios = CreateScenarioListForDeletion(); foreach (DesignScenario scenario in scenarios) { scenario.ClearResults(); scenario.ClearErrors(); } if (designCalculations != null) { designCalculations.Clear(); } } private EvaluationJob GetCalculatedEvaluationJob() { EvaluationJob evaluationJob = new EvaluationJob(); evaluationJob.DikeName = dike.Name; foreach (LocationJob locationJob in this.LocationJobs) { if ((locationJob.Result != JobResult.NoRun || (locationJob.HasRWScenarioResults)) && locationJob.Run != null && locationJob.Run.Value) { if (dike.Locations.Contains(locationJob.Location)) { dike.UpdateLocation(locationJob.Location); break; } evaluationJob.Locations.Add(locationJob.Location); } } return evaluationJob; } public bool HasResults() { bool hasResults = dike != null && dikeJob != null && dikeJob.Jobs.Count > 0; if (hasResults) { EvaluationJob evaluationJob = GetCalculatedEvaluationJob(); hasResults = evaluationJob.Locations != null && evaluationJob.Locations.Count > 0; } return hasResults; } /// /// Check if design with geometry adaption is allowed /// /// private bool IsDesignWithGeometryAdaptionAllowed() { bool isAdoption = this.DamProjectType == DamProjectType.Design && DamProjectCalculationSpecification.SelectedAnalysisType != AnalysisType.NoAdaption; bool isStabilityOutside = this.DamProjectCalculationSpecification.DamCalculationSpecifications.Any(specification => specification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityOutside); return (!isAdoption || !isStabilityOutside); } /// /// Validates the geometry adaption setting. /// /// [Validate] public ValidationResult[] ValidateGeometryAdaptionSetting() { if (!IsDesignWithGeometryAdaptionAllowed()) { return new[]{ new ValidationResult(ValidationResultType.Error, LocalizationManager.GetTranslatedText(this, "DesignAndAdaptionNotAllowedForStabilityOutside"), this)}; } else { return new ValidationResult[0]; } } public override string ToString() { return Name; } public void FillOverallSensorData() { if (sensorData != null) { sensorData.Sensors.Clear(); sensorData.SensorGroups.Clear(); sensorData.SensorLocations.Clear(); } else { sensorData = new SensorData(); } foreach (var location in dike.Locations) { var sd = location.SensorData; foreach (var sensor in sd.Sensors ) { if (sensorData.GetSensorById(sensor.ID) == null) { sensorData.Sensors.Add(sensor); } } if (sensorData.GetGroupById(sd.Group.ID) == null && sd.Group.ID >= 0) { sd.Group.PickSensors = sensorData.Sensors; sensorData.SensorGroups.Add(sd.Group); } if (sensorData.GetSensorLocationByLocationName(sd.LocationName) == null) { sensorData.SensorLocations.Add(sd); } } } } }