// 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;
using Core.Common.Base.Data;
using Core.Common.Base.Geometry;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Data.DikeProfiles;
using Ringtoets.Common.Data.Hydraulics;
using Ringtoets.Common.Data.Probabilistics;
using RingtoetsCommonDataResources = Ringtoets.Common.Data.Properties.Resources;
namespace Ringtoets.GrassCoverErosionInwards.Data
{
///
/// Class that holds all grass cover erosion inwards calculation specific input parameters.
///
public class GrassCoverErosionInwardsInput : CloneableObservable, ICalculationInput, IUseBreakWater, IUseForeshore
{
private const int orientationNumberOfDecimals = 2;
private static readonly Range orientationValidityRange = new Range(new RoundedDouble(orientationNumberOfDecimals),
new RoundedDouble(orientationNumberOfDecimals, 360));
private LogNormalDistribution criticalFlowRate;
private RoundedDouble orientation;
private RoundedDouble dikeHeight;
private DikeProfile dikeProfile;
///
/// Creates a new instance of .
///
public GrassCoverErosionInwardsInput()
{
orientation = new RoundedDouble(orientationNumberOfDecimals);
dikeHeight = new RoundedDouble(2);
SynchronizeDikeProfileInput();
criticalFlowRate = new LogNormalDistribution(4)
{
Mean = (RoundedDouble) 0.004,
StandardDeviation = (RoundedDouble) 0.0006
};
DikeHeightCalculationType = DikeHeightCalculationType.NoCalculation;
OvertoppingRateCalculationType = OvertoppingRateCalculationType.NoCalculation;
}
///
/// Gets or sets the dike profile.
///
public DikeProfile DikeProfile
{
get
{
return dikeProfile;
}
set
{
dikeProfile = value;
SynchronizeDikeProfileInput();
}
}
///
/// Gets or sets the orientation of the dike profile geometry with respect to North
/// in degrees. A positive value equals a clockwise rotation.
///
public RoundedDouble Orientation
{
get
{
return orientation;
}
set
{
RoundedDouble newOrientation = value.ToPrecision(orientation.NumberOfDecimalPlaces);
if (!double.IsNaN(newOrientation) && !orientationValidityRange.InRange(newOrientation))
{
throw new ArgumentOutOfRangeException(null, string.Format(RingtoetsCommonDataResources.Orientation_Value_needs_to_be_in_Range_0_,
orientationValidityRange));
}
orientation = newOrientation;
}
}
///
/// Gets the geometry of the dike with roughness data.
///
///
/// The roughness of a in the array represents
/// the roughness of the section between this
/// and the succeeding . The roughness of the last
/// point is irrelevant.
///
public IEnumerable DikeGeometry
{
get
{
return dikeProfile?.DikeGeometry ?? new RoughnessPoint[0];
}
}
///
/// Gets or sets the height of the dike [m+NAP].
///
public RoundedDouble DikeHeight
{
get
{
return dikeHeight;
}
set
{
dikeHeight = value.ToPrecision(dikeHeight.NumberOfDecimalPlaces);
}
}
///
/// Gets or sets the critical flow rate.
///
public LogNormalDistribution CriticalFlowRate
{
get
{
return criticalFlowRate;
}
set
{
criticalFlowRate.Mean = value.Mean;
criticalFlowRate.StandardDeviation = value.StandardDeviation;
}
}
///
/// Gets or sets the hydraulic boundary location.
///
public HydraulicBoundaryLocation HydraulicBoundaryLocation { get; set; }
///
/// Gets or sets how the dike height should be calculated.
///
public DikeHeightCalculationType DikeHeightCalculationType { get; set; }
///
/// Gets or sets how the overtopping rate should be calculated.
///
public OvertoppingRateCalculationType OvertoppingRateCalculationType { get; set; }
///
/// Gets or sets if the illustration points should be calculated for Dike Height.
///
public bool ShouldDikeHeightIllustrationPointsBeCalculated { get; set; }
///
/// Gets or sets if the illustration points should be calculated for Overtopping Flow.
///
public bool ShouldOvertoppingRateIllustrationPointsBeCalculated { get; set; }
///
/// Gets or sets if the illustration points should be calculated for Overtopping Output.
///
public bool ShouldOvertoppingOutputIllustrationPointsBeCalculated { get; set; }
///
/// Gets the value true if the parameters of the instance of
/// that are derived from
/// match the properties of
/// ; or false if this is not the case,
/// or if there is no assigned.
///
public bool IsDikeProfileInputSynchronized
{
get
{
if (dikeProfile == null)
{
return false;
}
BreakWater breakwater = dikeProfile.HasBreakWater
? new BreakWater(dikeProfile.BreakWater.Type, dikeProfile.BreakWater.Height)
: GetDefaultBreakWater();
return Equals(UseBreakWater, dikeProfile.HasBreakWater)
&& Equals(BreakWater, breakwater)
&& Equals(Orientation, dikeProfile.Orientation)
&& Equals(DikeHeight, dikeProfile.DikeHeight)
&& UseForeshore == dikeProfile.ForeshoreGeometry.Count() > 1;
}
}
public bool UseBreakWater { get; set; }
public BreakWater BreakWater { get; private set; }
public bool UseForeshore { get; set; }
public RoundedPoint2DCollection ForeshoreGeometry
{
get
{
return dikeProfile != null
? dikeProfile.ForeshoreGeometry
: new RoundedPoint2DCollection(2, Enumerable.Empty());
}
}
///
/// Applies the properties of the to the
/// parameters of the instance of .
///
/// When no dike profile is present, the input parameters are set to default values.
public void SynchronizeDikeProfileInput()
{
if (dikeProfile != null)
{
Orientation = dikeProfile.Orientation;
UseForeshore = dikeProfile.ForeshoreGeometry.Count() > 1;
UseBreakWater = dikeProfile.HasBreakWater;
BreakWater = dikeProfile.HasBreakWater
? new BreakWater(dikeProfile.BreakWater.Type, dikeProfile.BreakWater.Height)
: GetDefaultBreakWater();
DikeHeight = dikeProfile.DikeHeight;
}
else
{
SetDefaultDikeProfileProperties();
}
}
public override object Clone()
{
var clone = (GrassCoverErosionInwardsInput) base.Clone();
clone.criticalFlowRate = (LogNormalDistribution) CriticalFlowRate.Clone();
clone.BreakWater = (BreakWater) BreakWater.Clone();
return clone;
}
private void SetDefaultDikeProfileProperties()
{
Orientation = RoundedDouble.NaN;
UseForeshore = false;
UseBreakWater = false;
BreakWater = GetDefaultBreakWater();
DikeHeight = (RoundedDouble) double.NaN;
}
private static BreakWater GetDefaultBreakWater()
{
return new BreakWater(BreakWaterType.Dam, 0.0);
}
}
}