// 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) { Data = 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); } private static MacroStabilityInwardsSoilLayer2D ConvertLayerRecursively(SoilLayer2D soilLayer) { Ring outerRing = TransformSegmentsToRing(soilLayer.OuterLoop.Segments); Ring[] innerRings = soilLayer.InnerLoops.Select(il => TransformSegmentsToRing(il.Segments)).ToArray(); return new MacroStabilityInwardsSoilLayer2D(outerRing, innerRings) { Data = ConvertSoilLayerData(soilLayer), NestedLayers = 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) { return new MacroStabilityInwardsSoilLayerData { ShearStrengthModel = TransformShearStrengthModel(soilLayer.ShearStrengthModel), UsePop = TransformUsePop(soilLayer.UsePop), MaterialName = soilLayer.MaterialName, IsAquifer = TransformIsAquifer(soilLayer.IsAquifer), Color = SoilLayerColorConverter.Convert(soilLayer.Color), AbovePhreaticLevel = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) soilLayer.AbovePhreaticLevelMean, CoefficientOfVariation = (RoundedDouble) soilLayer.AbovePhreaticLevelCoefficientOfVariation, Shift = (RoundedDouble) soilLayer.AbovePhreaticLevelShift }, BelowPhreaticLevel = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) soilLayer.BelowPhreaticLevelMean, CoefficientOfVariation = (RoundedDouble) soilLayer.BelowPhreaticLevelCoefficientOfVariation, Shift = (RoundedDouble) soilLayer.BelowPhreaticLevelShift }, Cohesion = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) soilLayer.CohesionMean, CoefficientOfVariation = (RoundedDouble) soilLayer.CohesionCoefficientOfVariation }, FrictionAngle = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) soilLayer.FrictionAngleMean, CoefficientOfVariation = (RoundedDouble) soilLayer.FrictionAngleCoefficientOfVariation }, ShearStrengthRatio = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) soilLayer.ShearStrengthRatioMean, CoefficientOfVariation = (RoundedDouble) soilLayer.ShearStrengthRatioCoefficientOfVariation }, StrengthIncreaseExponent = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) soilLayer.StrengthIncreaseExponentMean, CoefficientOfVariation = (RoundedDouble) soilLayer.StrengthIncreaseExponentCoefficientOfVariation }, Pop = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) soilLayer.PopMean, CoefficientOfVariation = (RoundedDouble) soilLayer.PopCoefficientOfVariation } }; } /// /// Transforms a to a for the /// is aquifer property of soil layers. /// /// The value to transform. /// A based on . /// Thrown when /// could not be transformed. private static bool TransformIsAquifer(double? isAquifer) { try { return SoilLayerIsAquiferConverter.Convert(isAquifer); } catch (NotSupportedException) { throw new ImportedDataTransformException(string.Format(RingtoetsCommonIOResources.Transform_Invalid_value_ParameterName_0, RingtoetsCommonIOResources.SoilLayerData_IsAquifer_DisplayName)); } } /// /// Transforms a to a for the /// use POP property of soil layers. /// /// The value to transform. /// A based on . /// Thrown when /// could not be transformed. private static bool TransformUsePop(double? usePop) { if (!usePop.HasValue) { return true; } if (Math.Abs(usePop.Value) < tolerance) { return false; } throw new ImportedDataTransformException(string.Format(RingtoetsCommonIOResources.Transform_Invalid_value_ParameterName_0, Resources.SoilLayerData_UsePop_Description)); } /// /// Transforms a to a for the /// shear strength model of soil layers. /// /// The value to transform. /// A based /// on . /// Thrown when /// could not be transformed. private static MacroStabilityInwardsShearStrengthModel TransformShearStrengthModel(double? shearStrengthModel) { 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) { throw new ImportedDataTransformException(Resources.MacroStabilityInwardsSoilLayerTransformer_TransformShearStrengthModel_No_MacroStabilityInwardsShearStrengthModel); } throw new ImportedDataTransformException(string.Format(RingtoetsCommonIOResources.Transform_Invalid_value_ParameterName_0, Resources.SoilLayerData_ShearStrengthModel_Description)); } /// /// Transforms a collection of to . /// /// The segments to transform. /// A based on . /// Thrown when /// could not be transformed to a . private static Ring TransformSegmentsToRing(IEnumerable segments) { try { return new Ring(segments.Select(s => s.FirstPoint)); } catch (ArgumentException e) { throw new ImportedDataTransformException(Resources.MacroStabilityInwardsSoilLayerTransformer_TransformSegmentToRing_Invalid_geometry_for_Ring, 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) { DistributionHelper.ValidateIsLogNormal(soilLayer.AbovePhreaticLevelDistributionType, Resources.SoilLayerData_AbovePhreaticLevelDistribution_Description); DistributionHelper.ValidateIsLogNormal( soilLayer.BelowPhreaticLevelDistributionType, Resources.SoilLayerData_BelowPhreaticLevelDistribution_DisplayName); DistributionHelper.ValidateIsNonShiftedLogNormal( soilLayer.CohesionDistributionType, soilLayer.CohesionShift, Resources.SoilLayerData_CohesionDistribution_DisplayName); DistributionHelper.ValidateIsNonShiftedLogNormal( soilLayer.FrictionAngleDistributionType, soilLayer.FrictionAngleShift, Resources.SoilLayerData_FrictionAngleDistribution_DisplayName); DistributionHelper.ValidateIsNonShiftedLogNormal( soilLayer.ShearStrengthRatioDistributionType, soilLayer.ShearStrengthRatioShift, Resources.SoilLayerData_ShearStrengthRatioDistribution_DisplayName); DistributionHelper.ValidateIsNonShiftedLogNormal( soilLayer.StrengthIncreaseExponentDistributionType, soilLayer.StrengthIncreaseExponentShift, Resources.SoilLayerData_StrengthIncreaseExponentDistribution_DisplayName); DistributionHelper.ValidateIsNonShiftedLogNormal( soilLayer.PopDistributionType, soilLayer.PopShift, Resources.SoilLayerData_PopDistribution_DisplayName); } } }