// Copyright (C) Stichting Deltares 2021. All rights reserved.
//
// This file is part of Riskeer.
//
// Riskeer 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.Globalization;
using System.Linq;
using Core.Common.Base;
using Core.Common.Base.Data;
using Core.Common.Base.Geometry;
using Riskeer.Common.Data.Calculation;
using Riskeer.Common.Data.Hydraulics;
using Riskeer.Common.Data.Probabilistics;
using Riskeer.Piping.Data.Properties;
using Riskeer.Piping.Data.SoilProfile;
using Riskeer.Piping.Primitives;
namespace Riskeer.Piping.Data
{
///
/// Base class for piping calculation specific input parameters, i.e. values that can differ across various calculations.
///
public abstract class PipingInput : CloneableObservable, ICalculationInputWithHydraulicBoundaryLocation
{
private NormalDistribution phreaticLevelExit;
private LogNormalDistribution dampingFactorExit;
private RoundedDouble exitPointL;
private RoundedDouble entryPointL;
private PipingSurfaceLine surfaceLine;
///
/// Creates a new instance of .
///
protected PipingInput()
{
exitPointL = new RoundedDouble(2, double.NaN);
entryPointL = new RoundedDouble(2, double.NaN);
phreaticLevelExit = new NormalDistribution(3)
{
StandardDeviation = (RoundedDouble) 0.1
};
dampingFactorExit = new LogNormalDistribution(3)
{
Mean = (RoundedDouble) 0.7,
StandardDeviation = (RoundedDouble) 0.1
};
}
///
/// Gets or sets the l-coordinate of the entry point, which, together with
/// the l-coordinate of the exit point, is used to determine the seepage
/// length of .
/// [m]
///
/// Thrown when either:
///
/// - is smaller or equal to .
/// - does not fall within the local X-coordinate range of
///
///
public RoundedDouble EntryPointL
{
get
{
return entryPointL;
}
set
{
RoundedDouble newEntryPointL = value.ToPrecision(entryPointL.NumberOfDecimalPlaces);
if (!double.IsNaN(newEntryPointL))
{
if (!double.IsNaN(exitPointL))
{
ValidateEntryExitPoint(newEntryPointL, exitPointL);
}
if (surfaceLine != null)
{
ValidatePointOnSurfaceLine(newEntryPointL);
}
}
entryPointL = newEntryPointL;
}
}
///
/// Gets or sets the l-coordinate of the exit point, which, together with
/// the l-coordinate of the entry point, is used to determine the seepage
/// length of .
/// [m]
///
/// Thrown when either:
///
/// - is smaller or equal to .
/// - does not fall within the local X-coordinate range of
///
///
public RoundedDouble ExitPointL
{
get
{
return exitPointL;
}
set
{
RoundedDouble newExitPointL = value.ToPrecision(exitPointL.NumberOfDecimalPlaces);
if (!double.IsNaN(newExitPointL))
{
if (!double.IsNaN(entryPointL))
{
ValidateEntryExitPoint(entryPointL, newExitPointL);
}
if (surfaceLine != null)
{
ValidatePointOnSurfaceLine(newExitPointL);
}
}
exitPointL = newExitPointL;
}
}
///
/// Gets or sets the surface line.
///
public PipingSurfaceLine SurfaceLine
{
get
{
return surfaceLine;
}
set
{
surfaceLine = value;
SynchronizeEntryAndExitPointInput();
}
}
///
/// Gets or sets the stochastic soil model which is linked to the .
///
public PipingStochasticSoilModel StochasticSoilModel { get; set; }
///
/// Gets or sets the profile which contains a 1 dimensional definition of soil layers with properties.
///
public PipingStochasticSoilProfile StochasticSoilProfile { get; set; }
///
/// Gets the value true if the entry point and exit point of the
/// instance of match the entry point and
/// exit point of ; or false if this is
/// not the case, or if there is no assigned.
///
public bool IsEntryAndExitPointInputSynchronized
{
get
{
if (SurfaceLine == null)
{
return false;
}
double newEntryPointL;
double newExitPointL;
GetEntryExitPointFromSurfaceLine(out newEntryPointL, out newExitPointL);
return Math.Abs(newEntryPointL - EntryPointL) < 1e-6
&& Math.Abs(newExitPointL - ExitPointL) < 1e-6;
}
}
public HydraulicBoundaryLocation HydraulicBoundaryLocation { get; set; }
///
/// Applies the entry point and exit point of the to the
/// parameters of the instance of .
///
/// When no surface line is present, the entry and exit point are set to .
public void SynchronizeEntryAndExitPointInput()
{
if (SurfaceLine == null)
{
EntryPointL = RoundedDouble.NaN;
ExitPointL = RoundedDouble.NaN;
}
else
{
double tempEntryPointL;
double tempExitPointL;
GetEntryExitPointFromSurfaceLine(out tempEntryPointL, out tempExitPointL);
if (tempExitPointL <= ExitPointL)
{
EntryPointL = (RoundedDouble) tempEntryPointL;
ExitPointL = (RoundedDouble) tempExitPointL;
}
else
{
ExitPointL = (RoundedDouble) tempExitPointL;
EntryPointL = (RoundedDouble) tempEntryPointL;
}
}
}
public override object Clone()
{
var clone = (PipingInput) base.Clone();
clone.phreaticLevelExit = (NormalDistribution) PhreaticLevelExit.Clone();
clone.dampingFactorExit = (LogNormalDistribution) DampingFactorExit.Clone();
return clone;
}
private void GetEntryExitPointFromSurfaceLine(out double tempEntryPointL, out double tempExitPointL)
{
Point3D[] surfaceLineGeometry = SurfaceLine.Points.ToArray();
int entryPointIndex = Array.IndexOf(surfaceLineGeometry, SurfaceLine.DikeToeAtRiver);
int exitPointIndex = Array.IndexOf(surfaceLineGeometry, SurfaceLine.DikeToeAtPolder);
Point2D[] localGeometry = SurfaceLine.LocalGeometry.ToArray();
tempEntryPointL = localGeometry[0].X;
tempExitPointL = localGeometry[localGeometry.Length - 1].X;
bool isDifferentPoints = entryPointIndex < 0 || exitPointIndex < 0 || entryPointIndex < exitPointIndex;
if (isDifferentPoints && exitPointIndex > 0)
{
tempExitPointL = localGeometry.ElementAt(exitPointIndex).X;
}
if (isDifferentPoints && entryPointIndex > -1)
{
tempEntryPointL = localGeometry.ElementAt(entryPointIndex).X;
}
}
private static void ValidateEntryExitPoint(RoundedDouble entryPointLocalXCoordinate, RoundedDouble exitPointLocalXCoordinate)
{
if (entryPointLocalXCoordinate >= exitPointLocalXCoordinate)
{
throw new ArgumentOutOfRangeException(null, Resources.PipingInput_EntryPointL_greater_or_equal_to_ExitPointL);
}
}
private void ValidatePointOnSurfaceLine(RoundedDouble newLocalXCoordinate)
{
if (!surfaceLine.ValidateInRange(newLocalXCoordinate))
{
var validityRange = new Range(surfaceLine.LocalGeometry.First().X, surfaceLine.LocalGeometry.Last().X);
string outOfRangeMessage = string.Format(Resources.PipingInput_ValidatePointOnSurfaceLine_Length_must_be_in_Range_0_,
validityRange.ToString(FormattableConstants.ShowAtLeastOneDecimal, CultureInfo.CurrentCulture));
throw new ArgumentOutOfRangeException(null, outOfRangeMessage);
}
}
#region Probabilistic parameters
///
/// Gets or sets the phreatic level at the exit point.
/// [m]
///
public NormalDistribution PhreaticLevelExit
{
get
{
return phreaticLevelExit;
}
set
{
phreaticLevelExit.Mean = value.Mean;
phreaticLevelExit.StandardDeviation = value.StandardDeviation;
}
}
///
/// Gets or sets the damping factor at the exit point.
///
public LogNormalDistribution DampingFactorExit
{
get
{
return dampingFactorExit;
}
set
{
dampingFactorExit.Mean = value.Mean;
dampingFactorExit.StandardDeviation = value.StandardDeviation;
}
}
#endregion
}
}