// 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.Collections.Generic; using System.Linq; using Core.Common.Base.Data; using Ringtoets.Common.Service; using Ringtoets.Piping.Data; using Ringtoets.Piping.KernelWrapper; using Ringtoets.Piping.KernelWrapper.SubCalculator; using Ringtoets.Piping.Primitives; using Ringtoets.Piping.Service.Properties; using RingtoetsCommonServiceResources = Ringtoets.Common.Service.Properties.Resources; namespace Ringtoets.Piping.Service { /// /// This class is responsible for invoking operations on the . Error and status information is /// logged during the execution of the operation. /// public static class PipingCalculationService { /// /// Performs validation over the values on the given . Error and status information is logged during /// the execution of the operation. /// /// The for which to validate the values. /// False if contains validation errors; True otherwise. public static bool Validate(PipingCalculation calculation) { CalculationServiceHelper.LogValidationBeginTime(calculation.Name); CalculationServiceHelper.LogMessagesAsWarning(GetInputWarnings(calculation.InputParameters).ToArray()); var inputValidationResults = ValidateInput(calculation.InputParameters); if (inputValidationResults.Count > 0) { CalculationServiceHelper.LogMessagesAsError(RingtoetsCommonServiceResources.Error_in_validation_0, inputValidationResults.ToArray()); CalculationServiceHelper.LogValidationEndTime(calculation.Name); return false; } var validationResults = new PipingCalculator(CreateInputFromData(calculation.InputParameters), PipingSubCalculatorFactory.Instance).Validate(); CalculationServiceHelper.LogMessagesAsError(RingtoetsCommonServiceResources.Error_in_validation_0, validationResults.ToArray()); CalculationServiceHelper.LogValidationEndTime(calculation.Name); return validationResults.Count == 0; } /// /// Performs a piping calculation based on the supplied and sets /// based on the result if the calculation was successful. Error and status information is logged during /// the execution of the operation. /// /// The to base the input for the calculation upon. /// Consider calling first to see if calculation is possible. public static void Calculate(PipingCalculation calculation) { CalculationServiceHelper.LogCalculationBeginTime(calculation.Name); try { var pipingResult = new PipingCalculator(CreateInputFromData(calculation.InputParameters), PipingSubCalculatorFactory.Instance).Calculate(); calculation.Output = new PipingOutput(pipingResult.UpliftZValue, pipingResult.UpliftFactorOfSafety, pipingResult.HeaveZValue, pipingResult.HeaveFactorOfSafety, pipingResult.SellmeijerZValue, pipingResult.SellmeijerFactorOfSafety, pipingResult.HeaveGradient, pipingResult.SellmeijerCreepCoefficient, pipingResult.SellmeijerCriticalFall, pipingResult.SellmeijerReducedFall); } catch (PipingCalculatorException e) { CalculationServiceHelper.LogMessagesAsError(Resources.Error_in_piping_calculation_0, e.Message); } finally { CalculationServiceHelper.LogCalculationEndTime(calculation.Name); } } private static List ValidateInput(PipingInput inputParameters) { List validationResult = new List(); var isHydraulicBoundaryLocationMissing = inputParameters.HydraulicBoundaryLocation == null; var isSoilProfileMissing = inputParameters.StochasticSoilProfile == null; var isSurfaceLineMissing = inputParameters.SurfaceLine == null; var isExitPointLMissing = double.IsNaN(inputParameters.ExitPointL); var isEntryPointLMissing = double.IsNaN(inputParameters.EntryPointL); if (isHydraulicBoundaryLocationMissing) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_No_HydraulicBoundaryLocation_selected); } if (isSurfaceLineMissing) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_No_SurfaceLine_selected); } if (isSoilProfileMissing) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_No_StochasticSoilProfile_selected); } if (isEntryPointLMissing) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_No_value_for_EntryPointL); } if (isExitPointLMissing) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_No_value_for_ExitPointL); } if (!isHydraulicBoundaryLocationMissing) { if (double.IsNaN(inputParameters.AssessmentLevel)) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_Cannot_determine_AssessmentLevel); } if (double.IsNaN(inputParameters.PiezometricHeadExit)) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_Cannot_determine_PiezometricHeadExit); } } if (!isSurfaceLineMissing && !isSoilProfileMissing && !isExitPointLMissing) { if (double.IsNaN(inputParameters.ThicknessAquiferLayer.Mean)) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_Cannot_determine_thickness_aquifer_layer); } if (double.IsNaN(inputParameters.ThicknessCoverageLayer.Mean)) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_Cannot_determine_thickness_coverage_layer); } var pipingSoilProfile = inputParameters.StochasticSoilProfile.SoilProfile; var surfaceLevel = inputParameters.SurfaceLine.GetZAtL(inputParameters.ExitPointL); if (pipingSoilProfile != null) { IEnumerable consecutiveAquiferLayers = pipingSoilProfile.GetConsecutiveAquiferLayersBelowLevel(surfaceLevel).ToArray(); IEnumerable consecutiveCoverageLayers = pipingSoilProfile.GetConsecutiveCoverageLayersBelowLevel(surfaceLevel).ToArray(); var hasAquiferLayers = consecutiveAquiferLayers.Any(); var hasCoverageLayers = consecutiveCoverageLayers.Any(); if (!hasAquiferLayers) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_No_aquifer_layer_at_ExitPointL_under_SurfaceLine); } if (!hasCoverageLayers) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_No_coverage_layer_at_ExitPointL_under_SurfaceLine); } if (hasAquiferLayers) { if (double.IsNaN(inputParameters.DarcyPermeability.Mean) || double.IsNaN(inputParameters.DarcyPermeability.StandardDeviation)) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_Cannot_derive_DarcyPermeability); } if (double.IsNaN(inputParameters.Diameter70.Mean) || double.IsNaN(inputParameters.Diameter70.StandardDeviation)) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_Cannot_derive_Diameter70); } } if (hasCoverageLayers) { if (double.IsNaN(inputParameters.SaturatedVolumicWeightOfCoverageLayer.Mean) || double.IsNaN(inputParameters.SaturatedVolumicWeightOfCoverageLayer.StandardDeviation) || double.IsNaN(inputParameters.SaturatedVolumicWeightOfCoverageLayer.Shift)) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_Cannot_derive_SaturatedVolumicWeight); } else { var saturatedVolumicWeightOfCoverageLayer = PipingSemiProbabilisticDesignValueFactory.GetSaturatedVolumicWeightOfCoverageLayer(inputParameters).GetDesignValue(); if (saturatedVolumicWeightOfCoverageLayer < inputParameters.WaterVolumetricWeight) { validationResult.Add(Resources.PipingCalculationService_ValidateInput_SaturatedVolumicWeightCoverageLayer_must_be_larger_than_WaterVolumetricWeight); } } } } } return validationResult; } private static List GetInputWarnings(PipingInput inputParameters) { List warnings = new List(); var exitPointL = inputParameters.ExitPointL; var isSoilProfileMissing = inputParameters.StochasticSoilProfile == null; var isSurfaceLineMissing = inputParameters.SurfaceLine == null; var isExitPointLMissing = double.IsNaN(exitPointL); if (!isSurfaceLineMissing && !isSoilProfileMissing && !isExitPointLMissing) { var pipingSoilProfile = inputParameters.StochasticSoilProfile.SoilProfile; var surfaceLevel = inputParameters.SurfaceLine.GetZAtL(exitPointL); IEnumerable consecutiveAquiferLayersBelowLevel = pipingSoilProfile.GetConsecutiveAquiferLayersBelowLevel(surfaceLevel); IEnumerable consecutiveAquitardLayersBelowLevel = pipingSoilProfile.GetConsecutiveCoverageLayersBelowLevel(surfaceLevel); if (consecutiveAquiferLayersBelowLevel.Count() > 1) { warnings.Add(Resources.PipingCalculationService_GetInputWarnings_Multiple_aquifer_layers_Attempt_to_determine_values_for_DiameterD70_and_DarcyPermeability_from_top_layer); } if (consecutiveAquitardLayersBelowLevel.Count() > 1) { warnings.Add(Resources.PipingCalculationService_GetInputWarnings_Multiple_coverage_layers_Attempt_to_determine_value_from_combination); } if (!double.IsNaN(inputParameters.Diameter70.Mean) && !double.IsNaN(inputParameters.Diameter70.StandardDeviation)) { var diameter70Value = PipingSemiProbabilisticDesignValueFactory.GetDiameter70(inputParameters).GetDesignValue(); if (diameter70Value < 6.3e-5|| diameter70Value > 0.5e-3) { warnings.Add(string.Format(Resources.PipingCalculationService_GetInputWarnings_Specified_DiameterD70_value_0_not_in_valid_range_of_model, diameter70Value)); } } } return warnings; } private static PipingCalculatorInput CreateInputFromData(PipingInput inputParameters) { return new PipingCalculatorInput( inputParameters.WaterVolumetricWeight, PipingSemiProbabilisticDesignValueFactory.GetSaturatedVolumicWeightOfCoverageLayer(inputParameters).GetDesignValue(), inputParameters.UpliftModelFactor, inputParameters.AssessmentLevel, inputParameters.PiezometricHeadExit, PipingSemiProbabilisticDesignValueFactory.GetDampingFactorExit(inputParameters).GetDesignValue(), PipingSemiProbabilisticDesignValueFactory.GetPhreaticLevelExit(inputParameters).GetDesignValue(), inputParameters.CriticalHeaveGradient, PipingSemiProbabilisticDesignValueFactory.GetThicknessCoverageLayer(inputParameters).GetDesignValue(), inputParameters.SellmeijerModelFactor, inputParameters.SellmeijerReductionFactor, PipingSemiProbabilisticDesignValueFactory.GetSeepageLength(inputParameters).GetDesignValue(), inputParameters.SandParticlesVolumicWeight, inputParameters.WhitesDragCoefficient, PipingSemiProbabilisticDesignValueFactory.GetDiameter70(inputParameters).GetDesignValue(), PipingSemiProbabilisticDesignValueFactory.GetDarcyPermeability(inputParameters).GetDesignValue(), inputParameters.WaterKinematicViscosity, inputParameters.Gravity, PipingSemiProbabilisticDesignValueFactory.GetThicknessAquiferLayer(inputParameters).GetDesignValue(), inputParameters.MeanDiameter70, inputParameters.BeddingAngle, inputParameters.ExitPointL, inputParameters.SurfaceLine, inputParameters.StochasticSoilProfile.SoilProfile); } } }