// 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 Ringtoets.MacroStabilityInwards.Primitives;
namespace Ringtoets.MacroStabilityInwards.Data
{
///
/// Defines extension methods dealing with instances.
///
public static class MacroStabilityInwardsSoilProfileExtensions
{
///
/// Retrieves the thickness of the consecutive aquifer layers (if any) which are (partly) under a certain .
/// Only the thickness of the part of the aquifer layer under the level is determined.
///
/// The soil profile containing to consider.
/// The level under which the aquifer layers are sought.
/// The thickness of the part of the consecutive aquifer layer(s) (partly) under the .
public static double GetTopmostConsecutiveAquiferLayerThicknessBelowLevel(this PipingSoilProfile soilProfile, double level)
{
return TotalThicknessOfConsecutiveLayersBelowLevel(
soilProfile,
level,
soilProfile.GetConsecutiveAquiferLayersBelowLevel(level).ToArray());
}
///
/// Retrieves the thickness of the consecutive coverage layers (if any) which are (partly) under a certain .
/// Only the thickness of the part of the coverage layer under the level is determined.
///
/// The soil profile containing to consider.
/// The level under which the coverage layers are sought.
/// The thickness of the part of the consecutive coverage layer(s) (partly) under the .
public static double GetConsecutiveCoverageLayerThicknessBelowLevel(this PipingSoilProfile soilProfile, double level)
{
return TotalThicknessOfConsecutiveLayersBelowLevel(
soilProfile,
level,
soilProfile.GetConsecutiveCoverageLayersBelowLevel(level).ToArray());
}
///
/// Retrieves the collection of aquifer layers below a certain .
///
/// The soil profile containing to consider.
/// The level under which the aquifer layers are sought.
/// The collection of consecutive aquifer layer(s) (partly) under the .
public static IEnumerable GetConsecutiveAquiferLayersBelowLevel(this PipingSoilProfile soilProfile, double level)
{
return GetConsecutiveLayers(soilProfile, level, true);
}
///
/// Retrieves the collection of aquitard layers below a certain .
///
/// The soil profile containing to consider.
/// The level under which the aquitard layers are sought.
/// The collection of consecutive aquitard layer(s) (partly) under the .
public static IEnumerable GetConsecutiveCoverageLayersBelowLevel(this PipingSoilProfile soilProfile, double level)
{
PipingSoilLayer topAquiferLayer = soilProfile.GetConsecutiveAquiferLayersBelowLevel(level).FirstOrDefault();
if (topAquiferLayer != null)
{
PipingSoilLayer[] aquitardLayers = GetConsecutiveLayers(soilProfile, level, false).ToArray();
if (aquitardLayers.Any() && topAquiferLayer.Top < aquitardLayers.First().Top)
{
return aquitardLayers;
}
}
return Enumerable.Empty();
}
///
/// Calculates the thickness of a collection of consecutive .
///
/// The containing the .
/// The level under which to calculate the total thickness.
/// Collection of consecutive , ordered by
/// which are part of .
/// The total thickness of the consecutive layers below the given .
/// Thrown when either or
/// is null.
/// Thrown when the bottommost is not part of
/// .
private static double TotalThicknessOfConsecutiveLayersBelowLevel(PipingSoilProfile soilProfile, double level, PipingSoilLayer[] layers)
{
if (soilProfile == null)
{
throw new ArgumentNullException(nameof(soilProfile));
}
if (layers == null)
{
throw new ArgumentNullException(nameof(layers));
}
if (layers.Length == 0)
{
return double.NaN;
}
PipingSoilLayer bottomLayer = layers.Last();
PipingSoilLayer topLayer = layers.First();
return Math.Min(topLayer.Top, level) - (bottomLayer.Top - soilProfile.GetLayerThickness(bottomLayer));
}
///
/// Gets consecutive layers in the which have an aquifer property of .
///
/// The soil profile containing to consider.
/// The level under which the aquitard layers are sought.
/// Value indicating whether the consecutive layers should be aquifer or aquitard.
/// The collection of consecutive layer(s) with an aquifer property equal to
/// under the .
private static IEnumerable GetConsecutiveLayers(PipingSoilProfile soilProfile, double level, bool isAquifer)
{
if (level < soilProfile.Bottom)
{
yield break;
}
var yielding = false;
foreach (PipingSoilLayer soilLayer in soilProfile.Layers)
{
if (soilLayer.IsAquifer == isAquifer && IsSoilLayerPartlyBelowLevel(soilProfile, soilLayer, level))
{
yielding = true;
yield return soilLayer;
}
if (yielding && soilLayer.IsAquifer != isAquifer)
{
yield break;
}
}
}
private static bool IsSoilLayerPartlyBelowLevel(PipingSoilProfile soilProfile, PipingSoilLayer soilLayer, double level)
{
return soilLayer.Top < level || soilLayer.Top - soilProfile.GetLayerThickness(soilLayer) < level;
}
}
}