// 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);
}
}
}
}
}