// 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 log4net;
using Ringtoets.Piping.Calculation;
using Ringtoets.Piping.Calculation.SubCalculator;
using Ringtoets.Piping.Data;
using Ringtoets.Piping.Service.Properties;
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. At the end of an operation, a is returned,
/// representing the result of the operation.
///
public static class PipingCalculationService
{
private static readonly ILog pipingCalculationLogger = LogManager.GetLogger(typeof(PipingCalculation));
public static IPipingSubCalculatorFactory SubCalculatorFactory = new PipingSubCalculatorFactory();
///
/// 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)
{
pipingCalculationLogger.Info(String.Format(Resources.Validation_Subject_0_started_Time_1_,
calculation.Name, DateTimeService.CurrentTimeAsString));
var validationResults = new PipingCalculator(CreateInputFromData(calculation.InputParameters), SubCalculatorFactory).Validate();
LogMessagesAsError(Resources.Error_in_piping_validation_0, validationResults.ToArray());
pipingCalculationLogger.Info(String.Format(Resources.Validation_Subject_0_ended_Time_1_,
calculation.Name, DateTimeService.CurrentTimeAsString));
return validationResults.Count == 0;
}
///
/// Performs a piping calculation based on the supplied and sets
/// to the 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)
{
pipingCalculationLogger.Info(String.Format(Resources.Calculation_Subject_0_started_Time_1_,
calculation.Name, DateTimeService.CurrentTimeAsString));
try
{
var pipingResult = new PipingCalculator(CreateInputFromData(calculation.InputParameters), SubCalculatorFactory).Calculate();
calculation.Output = new PipingOutput(pipingResult.UpliftZValue,
pipingResult.UpliftFactorOfSafety,
pipingResult.HeaveZValue,
pipingResult.HeaveFactorOfSafety,
pipingResult.SellmeijerZValue,
pipingResult.SellmeijerFactorOfSafety);
}
catch (PipingCalculatorException e)
{
LogMessagesAsError(Resources.Error_in_piping_calculation_0, e.Message);
}
finally
{
pipingCalculationLogger.Info(String.Format(Resources.Calculation_Subject_0_ended_Time_1_,
calculation.Name, DateTimeService.CurrentTimeAsString));
}
}
private static void LogMessagesAsError(string format, params string[] errorMessages)
{
foreach (var errorMessage in errorMessages)
{
pipingCalculationLogger.ErrorFormat(format, errorMessage);
}
}
///
/// Calculates the thickness of the coverage layer based on the values of the .
///
/// The thickness of the coverage layer, or -1 if the thickness could not be calculated.
public static double CalculateThicknessCoverageLayer(PipingInput input)
{
try
{
return new PipingCalculator(CreateInputFromData(input), SubCalculatorFactory).CalculateThicknessCoverageLayer();
}
catch (PipingCalculatorException)
{
return double.NaN;
}
}
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.SoilProfile
);
}
public static double CalculatePiezometricHeadAtExit(PipingInput input)
{
return new PipingCalculator(CreateInputFromData(input), SubCalculatorFactory).CalculatePiezometricHeadAtExit();
}
}
}