// Copyright (C) Stichting Deltares 2017. 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.Linq; using Core.Common.Base.Data; using Core.Common.Base.Geometry; using Ringtoets.Common.Data.Probabilistics; using Ringtoets.Common.IO.Exceptions; using Ringtoets.Common.IO.SoilProfile; using Ringtoets.MacroStabilityInwards.Data.SoilProfile; using Ringtoets.MacroStabilityInwards.IO.Properties; using Ringtoets.MacroStabilityInwards.Primitives; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.MacroStabilityInwards.IO.SoilProfiles { /// /// Transforms generic into /// or . /// internal static class MacroStabilityInwardsSoilLayerTransformer { private const double tolerance = 1e-6; /// /// Transforms the generic into a /// . /// /// The soil layer to use in the transformation. /// A based on the given data. /// Thrown when is /// null. /// Thrown when transformation would not result /// in a valid transformed instance. public static MacroStabilityInwardsSoilLayer1D Transform(SoilLayer1D soilLayer) { if (soilLayer == null) { throw new ArgumentNullException(nameof(soilLayer)); } ValidateStochasticParameters(soilLayer); return new MacroStabilityInwardsSoilLayer1D(soilLayer.Top, ConvertSoilLayerData(soilLayer)); } /// /// Transforms the generic into a /// . /// /// The soil layer to use in the transformation. /// A based on the given data. /// Thrown when is /// null. /// Thrown when transformation would not result /// in a valid transformed instance. public static MacroStabilityInwardsSoilLayer2D Transform(SoilLayer2D soilLayer) { if (soilLayer == null) { throw new ArgumentNullException(nameof(soilLayer)); } ValidateStochasticParameters(soilLayer); return ConvertLayerRecursively(soilLayer); } /// /// Converts into . /// /// The soil layer to convert. /// The converted . /// Thrown when transformation would not result /// in a valid transformed instance. private static MacroStabilityInwardsSoilLayer2D ConvertLayerRecursively(SoilLayer2D soilLayer) { return new MacroStabilityInwardsSoilLayer2D(TransformSegmentsToRing(soilLayer.OuterLoop.Segments, soilLayer.MaterialName), ConvertSoilLayerData(soilLayer), soilLayer.NestedLayers.Select(ConvertLayerRecursively).ToArray()); } /// /// Converts into . /// /// The soil layer to get the data from. /// Thrown when transformation would not result /// in a valid transformed instance. private static MacroStabilityInwardsSoilLayerData ConvertSoilLayerData(SoilLayerBase soilLayer) { string soilLayerName = soilLayer.MaterialName; return new MacroStabilityInwardsSoilLayerData { ShearStrengthModel = TransformShearStrengthModel(soilLayer.ShearStrengthModel, soilLayerName), UsePop = TransformUsePop(soilLayer.UsePop, soilLayerName), MaterialName = soilLayerName, IsAquifer = TransformIsAquifer(soilLayer.IsAquifer, soilLayerName), Color = SoilLayerColorConverter.Convert(soilLayer.Color), AbovePhreaticLevel = TransformLogNormalDistribution(soilLayer.AbovePhreaticLevelMean, soilLayer.AbovePhreaticLevelCoefficientOfVariation, soilLayer.AbovePhreaticLevelShift, soilLayerName, "Onverzadigd gewicht"), BelowPhreaticLevel = TransformLogNormalDistribution(soilLayer.BelowPhreaticLevelMean, soilLayer.BelowPhreaticLevelCoefficientOfVariation, soilLayer.BelowPhreaticLevelShift, soilLayerName, "Verzadigd gewicht"), Cohesion = TransformLogNormalDistribution(soilLayer.CohesionMean, soilLayer.CohesionCoefficientOfVariation, soilLayerName, "Cohesie"), FrictionAngle = TransformLogNormalDistribution(soilLayer.FrictionAngleMean, soilLayer.FrictionAngleCoefficientOfVariation, soilLayerName, "Wrijvingshoek"), ShearStrengthRatio = TransformLogNormalDistribution(soilLayer.ShearStrengthRatioMean, soilLayer.ShearStrengthRatioCoefficientOfVariation, soilLayerName, "Schuifsterkte ratio (S)"), StrengthIncreaseExponent = TransformLogNormalDistribution(soilLayer.StrengthIncreaseExponentMean, soilLayer.StrengthIncreaseExponentCoefficientOfVariation, soilLayerName, "Sterkte toename exp (m)"), Pop = TransformLogNormalDistribution(soilLayer.PopMean, soilLayer.PopCoefficientOfVariation, soilLayerName, "POP") }; } /// /// Transforms the input arguments into a log normal distribution for a parameter of a soil layer. /// /// The mean of the distribution. /// The coefficient of variation of the distribution. /// The name of the soil layer. /// The name of the parameter to create a distribution for. /// A based on the input arguments. /// private static VariationCoefficientLogNormalDistribution TransformLogNormalDistribution(double mean, double coefficientOfVariation, string soilLayerName, string parameterName) { return TransformLogNormalDistribution(mean, coefficientOfVariation, new VariationCoefficientLogNormalDistribution().Shift, soilLayerName, parameterName); } /// /// Transforms the input arguments into a log normal distribution for a parameter of a soil layer. /// /// The mean of the distribution. /// The coefficient of variation of the distribution. /// The shift of the distribution. /// The name of the soil layer. /// The name of the parameter to create a distribution for. /// A based on the input arguments. /// private static VariationCoefficientLogNormalDistribution TransformLogNormalDistribution(double mean, double coefficientOfVariation, double shift, string soilLayerName, string parameterName) { try { return new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) mean, CoefficientOfVariation = (RoundedDouble) coefficientOfVariation, Shift = (RoundedDouble) shift }; } catch (ArgumentOutOfRangeException e) { string exceptionMessage = string.Format("Er is een fout opgetreden bij het inlezen van grondlaag '{0}' voor parameter '{1}': {2}", soilLayerName, parameterName, e.Message); throw new ImportedDataTransformException(exceptionMessage, e); } } /// /// Transforms a to a for the /// is aquifer property of soil layers. /// /// The value to transform. /// The name of the soil layer. /// A based on . /// Thrown when /// could not be transformed. private static bool TransformIsAquifer(double? isAquifer, string soilLayerName) { try { return SoilLayerIsAquiferConverter.Convert(isAquifer); } catch (NotSupportedException e) { string exceptionMessage = CreateErrorMessage(soilLayerName, string.Format(RingtoetsCommonIOResources.Transform_Invalid_value_ParameterName_0, RingtoetsCommonIOResources.SoilLayerData_IsAquifer_DisplayName)); throw new ImportedDataTransformException(exceptionMessage, e); } } /// /// Transforms a to a for the /// use POP property of soil layers. /// /// The value to transform. /// The name of the soil layer. /// A based on . /// Thrown when /// could not be transformed. private static bool TransformUsePop(double? usePop, string soilLayerName) { if (!usePop.HasValue) { return true; } if (Math.Abs(usePop.Value) < tolerance) { return false; } string exceptionMessage = CreateErrorMessage(soilLayerName, string.Format(RingtoetsCommonIOResources.Transform_Invalid_value_ParameterName_0, Resources.SoilLayerData_UsePop_Description)); throw new ImportedDataTransformException(exceptionMessage); } /// /// Transforms a to a for the /// shear strength model of soil layers. /// /// The value to transform. /// The name of the soil layer. /// A based /// on . /// Thrown when /// could not be transformed. private static MacroStabilityInwardsShearStrengthModel TransformShearStrengthModel(double? shearStrengthModel, string soilLayerName) { string exceptionMessage; if (!shearStrengthModel.HasValue) { return MacroStabilityInwardsShearStrengthModel.CPhi; } if (Math.Abs(shearStrengthModel.Value - 6) < tolerance) { return MacroStabilityInwardsShearStrengthModel.SuCalculated; } if (Math.Abs(shearStrengthModel.Value - 9) < tolerance) { return MacroStabilityInwardsShearStrengthModel.CPhiOrSuCalculated; } if (Math.Abs(shearStrengthModel.Value - 1) < tolerance) { exceptionMessage = CreateErrorMessage(soilLayerName, Resources.MacroStabilityInwardsSoilLayerTransformer_TransformShearStrengthModel_No_MacroStabilityInwardsShearStrengthModel); throw new ImportedDataTransformException(exceptionMessage); } exceptionMessage = CreateErrorMessage(soilLayerName, string.Format(RingtoetsCommonIOResources.Transform_Invalid_value_ParameterName_0, Resources.SoilLayerData_ShearStrengthModel_Description)); throw new ImportedDataTransformException(exceptionMessage); } /// /// Transforms a collection of to . /// /// The segments to transform. /// The name of the soil layer. /// A based on . /// Thrown when /// could not be transformed to a . private static Ring TransformSegmentsToRing(IEnumerable segments, string soilLayerName) { try { return new Ring(segments.Select(s => s.FirstPoint)); } catch (ArgumentException e) { string exceptionMessage = CreateErrorMessage(soilLayerName, Resources.MacroStabilityInwardsSoilLayerTransformer_TransformSegmentToRing_Invalid_geometry_for_Ring); throw new ImportedDataTransformException(exceptionMessage, e); } } /// /// Validates whether the values of the distribution and shift for the stochastic parameters /// are correct for creating a soil layer. /// /// The soil layer to validate. /// Thrown when any of the distributions of the /// stochastic parameters is not defined as log normal or is shifted when it should not be. private static void ValidateStochasticParameters(SoilLayerBase soilLayer) { try { DistributionHelper.ValidateShiftedLogNormalDistribution(soilLayer.AbovePhreaticLevelDistributionType, Resources.SoilLayerData_AbovePhreaticLevelDistribution_Description); DistributionHelper.ValidateShiftedLogNormalDistribution( soilLayer.BelowPhreaticLevelDistributionType, Resources.SoilLayerData_BelowPhreaticLevelDistribution_DisplayName); DistributionHelper.ValidateLogNormalDistribution( soilLayer.CohesionDistributionType, soilLayer.CohesionShift, Resources.SoilLayerData_CohesionDistribution_DisplayName); DistributionHelper.ValidateLogNormalDistribution( soilLayer.FrictionAngleDistributionType, soilLayer.FrictionAngleShift, Resources.SoilLayerData_FrictionAngleDistribution_DisplayName); DistributionHelper.ValidateLogNormalDistribution( soilLayer.ShearStrengthRatioDistributionType, soilLayer.ShearStrengthRatioShift, Resources.SoilLayerData_ShearStrengthRatioDistribution_DisplayName); DistributionHelper.ValidateLogNormalDistribution( soilLayer.StrengthIncreaseExponentDistributionType, soilLayer.StrengthIncreaseExponentShift, Resources.SoilLayerData_StrengthIncreaseExponentDistribution_DisplayName); DistributionHelper.ValidateLogNormalDistribution( soilLayer.PopDistributionType, soilLayer.PopShift, Resources.SoilLayerData_PopDistribution_DisplayName); } catch (ImportedDataTransformException e) { string errorMessage = CreateErrorMessage(soilLayer.MaterialName, e.Message); throw new ImportedDataTransformException(errorMessage, e); } } private static string CreateErrorMessage(string soilLayerName, string errorMessage) { return string.Format(RingtoetsCommonIOResources.Transform_Error_occurred_when_transforming_SoilLayer_0_errorMessage_1, soilLayerName, errorMessage); } } }