// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU 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 General Public License for more details. // // You should have received a copy of the GNU 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.Collections.Specialized; using System.Globalization; using System.Linq; using Ringtoets.HydraRing.Calculation.Data; using Ringtoets.HydraRing.Calculation.Settings; namespace Ringtoets.HydraRing.Calculation { /// /// Container for all configurations that are necessary for performing a Hydra-Ring calculation. /// The following Hydra-Ring features are not exposed (yet): /// /// /// Combination of multiple dike sections /// /// /// Coupling two hydraulic boundary stations /// /// /// Performing revetment calculations (DesignTables > LayerId) /// /// /// Performing piping calculations (DesignTables > AlternativeId) /// /// /// Type 3 computations (DesignTables > Method) /// /// /// In the end, the configuration can be used to generate a Hydra-Ring database creation script. /// public class HydraRingConfiguration { private readonly string ringId; private readonly IList hydraRingCalculations; private readonly SubMechanismSettingsProvider subMechanismSettingsProvider = new SubMechanismSettingsProvider(); private readonly FailureMechanismSettingsProvider failureMechanismSettingsProvider = new FailureMechanismSettingsProvider(); private readonly FailureMechanismDefaultsProvider failureMechanismDefaultsProvider = new FailureMechanismDefaultsProvider(); private readonly VariableDefaultsProvider variableDefaultsProvider = new VariableDefaultsProvider(); private readonly HydraRingTimeIntegrationSchemeType timeIntegrationSchemeType; private readonly HydraRingUncertaintiesType uncertaintiesType; /// /// Creates a new instance of the class. /// /// The id of the ring to perform the configured Hydra-Ring calculations for. /// The to use while executing the configured Hydra-Ring calculations. /// The to use while executing the configured Hydra-Ring calculations. public HydraRingConfiguration(string ringId, HydraRingTimeIntegrationSchemeType timeIntegrationSchemeType, HydraRingUncertaintiesType uncertaintiesType) { hydraRingCalculations = new List(); this.ringId = ringId; this.timeIntegrationSchemeType = timeIntegrationSchemeType; this.uncertaintiesType = uncertaintiesType; } /// /// Gets the id of the ring to perform the configured Hydra-Ring calculations for. /// public string RingId { get { return ringId; } } /// /// Gets the to use while executing the configured Hydra-Ring calculations. /// public HydraRingTimeIntegrationSchemeType? TimeIntegrationSchemeType { get { return timeIntegrationSchemeType; } } /// /// Gets the to use while executing the configured Hydra-Ring calculations. /// public HydraRingUncertaintiesType? UncertaintiesType { get { return uncertaintiesType; } } /// /// Adds a Hydra-Ring calculation to the . /// /// The container that holds all data for configuring the calculation. public void AddHydraRingCalculation(HydraRingCalculation hydraRingCalculation) { hydraRingCalculations.Add(hydraRingCalculation); } /// /// Generates a database creation script that can be used to perform a Hydra-Ring calculation. /// /// The database creation script. /// Thrown when one of the relevant input properties is not set. public string GenerateDataBaseCreationScript() { var configurationDictionary = new Dictionary>(); InitializeHydraulicModelsConfiguration(configurationDictionary); InitializeSectionsConfiguration(configurationDictionary); InitializeDesignTablesConfiguration(configurationDictionary); InitializeNumericsConfiguration(configurationDictionary); InitializeVariableDatasConfiguration(configurationDictionary); InitializeCalculationProfilesConfiguration(configurationDictionary); InitializeSectionFaultTreeModelsConfiguration(configurationDictionary); InitializeSectionSubMechanismModelsConfiguration(configurationDictionary); InitializeFetchesConfiguration(configurationDictionary); InitializeAreaPointsConfiguration(configurationDictionary); InitializePresentationSectionsConfiguration(configurationDictionary); InitializeProfilesConfiguration(configurationDictionary); InitializeForelandModelsConfiguration(configurationDictionary); InitializeForelandsConfiguration(configurationDictionary); InitializeProbabilityAlternativesConfiguration(configurationDictionary); InitializeSetUpHeightsConfiguration(configurationDictionary); InitializeCalcWindDirectionsConfiguration(configurationDictionary); InitializeSwellsConfiguration(configurationDictionary); InitializeWaveReductionsConfiguration(configurationDictionary); InitializeAreasConfiguration(configurationDictionary); InitializeProjectsConfiguration(configurationDictionary); return GenerateDataBaseCreationScript(configurationDictionary); } private void InitializeHydraulicModelsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["HydraulicModels"] = new List { new OrderedDictionary { { "TimeIntegrationSchemeID", (int?) TimeIntegrationSchemeType }, { "UncertaintiesID", (int?) UncertaintiesType }, { "DataSetName", "WTI 2017" // Fixed: use the WTI 2017 set of station locations } } }; } private void InitializeSectionsConfiguration(Dictionary> configurationDictionary) { var orderedDictionaries = new List(); foreach (var hydraRingCalculation in hydraRingCalculations) { var hydraRingDikeSection = hydraRingCalculation.DikeSection; orderedDictionaries.Add(new OrderedDictionary { { "SectionId", hydraRingDikeSection.SectionId }, { "PresentationId", 1 // Fixed: no support for combination of multiple dike sections }, { "MainMechanismId", 1 // Fixed: no support for combination of multiple dike sections }, { "Name", hydraRingDikeSection.SectionName }, { "Description", hydraRingDikeSection.SectionName // Just use the section name }, { "RingCoordinateBegin", GetHydraRingValue(hydraRingDikeSection.SectionBeginCoordinate) }, { "RingCoordinateEnd", GetHydraRingValue(hydraRingDikeSection.SectionEndCoordinate) }, { "XCoordinate", GetHydraRingValue(hydraRingDikeSection.CrossSectionXCoordinate) }, { "YCoordinate", GetHydraRingValue(hydraRingDikeSection.CrossSectionYCoordinate) }, { "StationId1", hydraRingCalculation.HydraulicBoundaryLocationId }, { "StationId2", hydraRingCalculation.HydraulicBoundaryLocationId // Same as "StationId1": no support for coupling two stations }, { "Relative", 100.0 // Fixed: no support for coupling two stations }, { "Normal", GetHydraRingValue(hydraRingDikeSection.CrossSectionNormal) }, { "Length", GetHydraRingValue(hydraRingDikeSection.SectionLength) } }); } configurationDictionary["Sections"] = orderedDictionaries; } private void InitializeDesignTablesConfiguration(Dictionary> configurationDictionary) { var orderedDictionaries = new List(); foreach (var hydraRingCalculation in hydraRingCalculations) { var failureMechanismDefaults = failureMechanismDefaultsProvider.GetFailureMechanismDefaults(hydraRingCalculation.FailureMechanismType); var failureMechanismSettings = failureMechanismSettingsProvider.GetFailureMechanismSettings(hydraRingCalculation.FailureMechanismType); orderedDictionaries.Add(new OrderedDictionary { { "SectionId", hydraRingCalculation.DikeSection.SectionId }, { "MechanismId", failureMechanismDefaults.MechanismId }, { "LayerId", null // Fixed: no support for revetments }, { "AlternativeId", null // Fixed: no support for piping }, { "Method", failureMechanismDefaults.CalculationTypeId }, { "VariableId", failureMechanismDefaults.VariableId }, { "LoadVariableId", null // Fixed: not relevant }, { "TableMin", null // Fixed: no support for type 3 computations (see "Method") }, { "TableMax", null // Fixed: no support for type 3 computations (see "Method") }, { "TableStepSize", null // Fixed: no support for type 3 computations (see "Method") }, { "ValueMin", GetHydraRingValue(failureMechanismSettings.ValueMin) }, { "ValueMax", GetHydraRingValue(failureMechanismSettings.ValueMax) }, { "Beta", GetHydraRingValue(hydraRingCalculation.Beta) } }); } configurationDictionary["DesignTables"] = orderedDictionaries; } private void InitializeNumericsConfiguration(Dictionary> configurationDictionary) { var orderDictionaries = new List(); foreach (var hydraRingCalculation in hydraRingCalculations) { var failureMechanismDefaults = failureMechanismDefaultsProvider.GetFailureMechanismDefaults(hydraRingCalculation.FailureMechanismType); foreach (var subMechanimsId in failureMechanismDefaults.SubMechanismIds) { var subMechanismSettings = subMechanismSettingsProvider.GetSubMechanismSettings(hydraRingCalculation.FailureMechanismType, subMechanimsId, ringId); orderDictionaries.Add(new OrderedDictionary { { "SectionId", hydraRingCalculation.DikeSection.SectionId }, { "MechanismId", failureMechanismDefaults.MechanismId }, { "LayerId", null // Fixed: no support for revetments }, { "AlternativeId", null // Fixed: no support for piping }, { "SubMechanismId", subMechanimsId }, { "Method", subMechanismSettings.CalculationTechniqueId }, { "FormStartMethod", subMechanismSettings.FormStartMethod }, { "FormNumberOfIterations", subMechanismSettings.FormNumberOfIterations }, { "FormRelaxationFactor", GetHydraRingValue(subMechanismSettings.FormRelaxationFactor) }, { "FormEpsBeta", GetHydraRingValue(subMechanismSettings.FormEpsBeta) }, { "FormEpsHOH", GetHydraRingValue(subMechanismSettings.FormEpsHoh) }, { "FormEpsZFunc", GetHydraRingValue(subMechanismSettings.FormEpsZFunc) }, { "DsStartMethod", subMechanismSettings.DsStartMethod }, { "DsIterationmethod", 1 // Fixed: not relevant }, { "DsMinNumberOfIterations", subMechanismSettings.DsMinNumberOfIterations }, { "DsMaxNumberOfIterations", subMechanismSettings.DsMaxNumberOfIterations }, { "DsVarCoefficient", GetHydraRingValue(subMechanismSettings.DsVarCoefficient) }, { "NiUMin", GetHydraRingValue(subMechanismSettings.NiUMin) }, { "NiUMax", GetHydraRingValue(subMechanismSettings.NiUMax) }, { "NiNumberSteps", subMechanismSettings.NiNumberSteps } }); } } configurationDictionary["Numerics"] = orderDictionaries; } private void InitializeVariableDatasConfiguration(Dictionary> configurationDictionary) { var orderDictionaries = new List(); foreach (var hydraRingCalculation in hydraRingCalculations) { var failureMechanismDefaults = failureMechanismDefaultsProvider.GetFailureMechanismDefaults(hydraRingCalculation.FailureMechanismType); foreach (var hydraRingVariable in hydraRingCalculation.Variables) { var variableDefaults = variableDefaultsProvider.GetVariableDefaults(hydraRingCalculation.FailureMechanismType, hydraRingVariable.VariableId); orderDictionaries.Add(new OrderedDictionary { { "SectionId", hydraRingCalculation.DikeSection.SectionId }, { "MechanismId", failureMechanismDefaults.MechanismId }, { "LayerId", null // Fixed: no support for revetments }, { "AlternativeId", null // Fixed: no support for piping }, { "VariableId", hydraRingVariable.VariableId }, { "Value", hydraRingVariable.DistributionType == HydraRingDistributionType.Deterministic ? GetHydraRingValue(hydraRingVariable.Value) : null }, { "DistributionType", (int?) hydraRingVariable.DistributionType }, { "Parameter1", hydraRingVariable.DistributionType != HydraRingDistributionType.Deterministic ? GetHydraRingValue(hydraRingVariable.Mean) : null }, { "Parameter2", hydraRingVariable.DistributionType != HydraRingDistributionType.Deterministic && hydraRingVariable.DeviationType == HydraRingDeviationType.Standard ? GetHydraRingValue(hydraRingVariable.Variability) : null }, { "Parameter3", hydraRingVariable.DistributionType == HydraRingDistributionType.LogNormal ? GetHydraRingValue(hydraRingVariable.Shift) : null }, { "Parameter4", null // Fixed: Not relevant }, { "DeviationType", (int?) hydraRingVariable.DeviationType }, { "CoefficientOfVariation", hydraRingVariable.DistributionType != HydraRingDistributionType.Deterministic && hydraRingVariable.DeviationType == HydraRingDeviationType.Variation ? GetHydraRingValue(hydraRingVariable.Variability) : null }, { "CorrelationLength", GetHydraRingValue(variableDefaults.CorrelationLength) } }); } } configurationDictionary["VariableDatas"] = orderDictionaries; } private void InitializeCalculationProfilesConfiguration(Dictionary> configurationDictionary) { var orderDictionaries = new List(); foreach (var hydraRingCalculation in hydraRingCalculations) { for (var i = 0; i < hydraRingCalculation.ProfilePoints.Count(); i++) { var hydraRingProfilePoint = hydraRingCalculation.ProfilePoints.ElementAt(i); orderDictionaries.Add(new OrderedDictionary { { "SectionId", hydraRingCalculation.DikeSection.SectionId }, { "SequenceNumber", i + 1 }, { "XCoordinate", GetHydraRingValue(hydraRingProfilePoint.X) }, { "ZCoordinate", GetHydraRingValue(hydraRingProfilePoint.Z) }, { "Roughness", GetHydraRingValue(hydraRingProfilePoint.Roughness) } }); } } configurationDictionary["CalculationProfiles"] = orderDictionaries; } private void InitializeSectionFaultTreeModelsConfiguration(Dictionary> configurationDictionary) { var orderedDictionaries = new List(); foreach (var hydraRingCalculation in hydraRingCalculations) { var failureMechanismDefaults = failureMechanismDefaultsProvider.GetFailureMechanismDefaults(hydraRingCalculation.FailureMechanismType); var failureMechanismSettings = failureMechanismSettingsProvider.GetFailureMechanismSettings(hydraRingCalculation.FailureMechanismType); orderedDictionaries.Add(new OrderedDictionary { { "SectionId", hydraRingCalculation.DikeSection.SectionId }, { "MechanismId", failureMechanismDefaults.MechanismId }, { "LayerId", null // Fixed: no support for revetments }, { "AlternativeId", null // Fixed: no support for piping }, { "FaultTreeModelId", failureMechanismSettings.FaultTreeModelId } }); } configurationDictionary["SectionFaultTreeModels"] = orderedDictionaries; } private void InitializeSectionSubMechanismModelsConfiguration(Dictionary> configurationDictionary) { var orderedDictionaries = new List(); foreach (var hydraRingCalculation in hydraRingCalculations) { var failureMechanismDefaults = failureMechanismDefaultsProvider.GetFailureMechanismDefaults(hydraRingCalculation.FailureMechanismType); foreach (var subMechanismId in failureMechanismDefaults.SubMechanismIds) { var subMechanismModelId = hydraRingCalculation.GetSubMechanismModelId(subMechanismId); if (subMechanismModelId != null) { orderedDictionaries.Add(new OrderedDictionary { { "SectionId", hydraRingCalculation.DikeSection.SectionId }, { "MechanismId", failureMechanismDefaults.MechanismId }, { "LayerId", null // Fixed: no support for revetments }, { "AlternativeId", null // Fixed: no support for piping }, { "SubMechanismId", subMechanismId }, { "SubMechanismModelId", subMechanismModelId } }); } } } configurationDictionary["SectionSubMechanismModels"] = orderedDictionaries; } private void InitializeFetchesConfiguration(Dictionary> configurationDictionary) { configurationDictionary["Fetches"] = new List(); } private void InitializeAreaPointsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["AreaPoints"] = new List(); } private void InitializePresentationSectionsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["PresentationSections"] = new List(); } private void InitializeProfilesConfiguration(Dictionary> configurationDictionary) { configurationDictionary["Profiles"] = new List(); } private void InitializeForelandModelsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["ForelandModels"] = new List(); } private void InitializeForelandsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["Forelands"] = new List(); } private void InitializeProbabilityAlternativesConfiguration(Dictionary> configurationDictionary) { configurationDictionary["ProbabilityAlternatives"] = new List(); } private void InitializeSetUpHeightsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["SetUpHeights"] = new List(); } private void InitializeCalcWindDirectionsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["CalcWindDirections"] = new List(); } private void InitializeSwellsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["Swells"] = new List(); } private void InitializeWaveReductionsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["WaveReductions"] = new List(); } private void InitializeAreasConfiguration(Dictionary> configurationDictionary) { configurationDictionary["Areas"] = new List { new OrderedDictionary { { "aDefault", 1 // Fixed: not relevant }, { "bDefault", "1" // Fixed: not relevant }, { "cDefault", "Nederland" // Fixed: not relevant } } }; } private void InitializeProjectsConfiguration(Dictionary> configurationDictionary) { configurationDictionary["Projects"] = new List { new OrderedDictionary { { "aDefault", 1 // Fixed: not relevant }, { "bDefault", "WTI 2017" // Fixed: not relevant }, { "cDefault", "Ringtoets calculation" // Fixed: not relevant } } }; } private static string GenerateDataBaseCreationScript(Dictionary> configurationDictionary) { var lines = new List(); foreach (var tableName in configurationDictionary.Keys) { lines.Add("DELETE FROM [" + tableName + "];"); if (configurationDictionary[tableName].Count <= 0) { lines.Add(""); continue; } foreach (var orderedDictionary in configurationDictionary[tableName]) { var valueStrings = new List(); foreach (var val in orderedDictionary.Values) { if (val == null) { valueStrings.Add("NULL"); continue; } if (val is string) { valueStrings.Add("'" + val + "'"); continue; } if (val is double) { valueStrings.Add(((double) val).ToString(CultureInfo.InvariantCulture)); continue; } valueStrings.Add(val.ToString()); } var valuesString = string.Join(", ", valueStrings); lines.Add("INSERT INTO [" + tableName + "] VALUES (" + valuesString + ");"); } lines.Add(""); } return string.Join(Environment.NewLine, lines); } private double? GetHydraRingValue(double value) { return !double.IsNaN(value) ? (double?) value : null; } } }