Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile1D.cs =================================================================== diff -u -r4000 -r4052 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile1D.cs (.../SoilProfile1D.cs) (revision 4000) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile1D.cs (.../SoilProfile1D.cs) (revision 4052) @@ -27,655 +27,654 @@ using Deltares.DamEngine.Data.Standard.Language; using Deltares.DamEngine.Data.Standard.Validation; -namespace Deltares.DamEngine.Data.Geotechnics +namespace Deltares.DamEngine.Data.Geotechnics; + +/// +/// Interface for providing the 1D Soil Profile +/// +public interface ISoilProfileProvider { /// - /// Interface for providing the 1D Soil Profile + /// Gets the soil profile. /// - public interface ISoilProfileProvider + /// + /// The soil profile. + /// + SoilProfile1D SoilProfile { get; } +} + +/// +/// 1D Soil Profile Object +/// +public class SoilProfile1D : SoilProfile +{ + private const double DefaultBottomLayerHeight = 20.0; + + private readonly DelegatedList layers = new DelegatedList(); + private double bottomLevel = double.NaN; + + /// + /// Default constructor + /// + public SoilProfile1D() { - /// - /// Gets the soil profile. - /// - /// - /// The soil profile. - /// - SoilProfile1D SoilProfile { get; } + base.Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSoilProfile1D"); + layers.AddMethod = AddLayer; } /// - /// 1D Soil Profile Object + /// Constructor to construct simple soilprofile /// - public class SoilProfile1D : SoilProfile + /// + /// + /// + public SoilProfile1D(double topLevel, double bottomLevel, Soil soil) + : this() { - private const double DefaultBottomLayerHeight = 20.0; + this.bottomLevel = bottomLevel; + layers.Add(new SoilLayer1D(soil, topLevel)); + } - private readonly DelegatedList layers = new DelegatedList(); - private double bottomLevel = double.NaN; - - /// - /// Default constructor - /// - public SoilProfile1D() + /// + /// Gets the soil layer collection for this profile + /// + public IList Layers + { + get { - base.Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSoilProfile1D"); - layers.AddMethod = AddLayer; + return layers; } + } - /// - /// Constructor to construct simple soilprofile - /// - /// - /// - /// - public SoilProfile1D(double topLevel, double bottomLevel, Soil soil) - : this() + /// + /// Gets the number of layers. + /// + /// + /// The layer count. + /// + public int LayerCount + { + get { - this.bottomLevel = bottomLevel; - layers.Add(new SoilLayer1D(soil, topLevel)); + return layers.Count; } + } - /// - /// Gets the soil layer collection for this profile - /// - public IList Layers + /// + /// Gets or sets the bottom level. + /// + /// + /// The bottom level. + /// + public double BottomLevel + { + get { - get + if (double.IsNaN(bottomLevel) && layers.Count > 0) { - return layers; + bottomLevel = Layers.Last().TopLevel - DefaultBottomLayerHeight; } - } - /// - /// Gets the number of layers. - /// - /// - /// The layer count. - /// - public int LayerCount - { - get - { - return layers.Count; - } + return bottomLevel; } - - /// - /// Gets or sets the bottom level. - /// - /// - /// The bottom level. - /// - public double BottomLevel + set { - get + if (double.IsNaN(bottomLevel) || (Math.Abs(value - bottomLevel) > GeometryConstants.Accuracy)) { - if (double.IsNaN(bottomLevel) && layers.Count > 0) - { - bottomLevel = Layers.Last().TopLevel - DefaultBottomLayerHeight; - } - - return bottomLevel; + bottomLevel = value; } - set - { - if (double.IsNaN(bottomLevel) || (Math.Abs(value - bottomLevel) > GeometryConstants.Accuracy)) - { - bottomLevel = value; - } - } } + } - /// - /// Gets or sets the top level. - /// - /// - /// The top level. - /// - public double TopLevel + /// + /// Gets or sets the top level. + /// + /// + /// The top level. + /// + public double TopLevel + { + get { - get - { - return layers.Any() ? layers.First().TopLevel : BottomLevel; - } + return layers.Any() ? layers.First().TopLevel : BottomLevel; } + } - /// - /// Gets the infiltration layer. - /// - /// - /// The infiltration layer. - /// - public SoilLayer1D InfiltrationLayer { get; private set; } + /// + /// Gets the infiltration layer. + /// + /// + /// The infiltration layer. + /// + public SoilLayer1D InfiltrationLayer { get; private set; } - /// - /// Gets the toppest aquifer layer of the deepest cluster of aquifers - /// - /// - /// The toppest aquifer layer in the deepest cluster of aquifers - /// - public SoilLayer1D BottomAquiferLayer + /// + /// Gets the toppest aquifer layer of the deepest cluster of aquifers + /// + /// + /// The toppest aquifer layer in the deepest cluster of aquifers + /// + public SoilLayer1D BottomAquiferLayer + { + get { - get + IList sortedLayers = Layers.OrderBy(l => l.TopLevel).ToList(); + SoilLayer1D aquiferLayer = null; + int aquiferIndex = -1; + + // Search deepest aquifer layer + for (var layerIndex = 0; layerIndex < sortedLayers.Count; layerIndex++) { - IList sortedLayers = Layers.OrderBy(l => l.TopLevel).ToList(); - SoilLayer1D aquiferLayer = null; - int aquiferIndex = -1; + SoilLayer1D layer = sortedLayers[layerIndex]; + if (IsAquiferLayer(layer)) + { + aquiferIndex = layerIndex; + aquiferLayer = layer; + break; + } + } - // Search deepest aquifer layer - for (var layerIndex = 0; layerIndex < sortedLayers.Count; layerIndex++) + // aquifer may consists of more then 1 connected (aquifer) layers + // Search all layers above the first found aquifer to find top aquifer layer + if (aquiferIndex >= 0) + { + for (int layerIndex = aquiferIndex + 1; layerIndex < sortedLayers.Count; layerIndex++) { SoilLayer1D layer = sortedLayers[layerIndex]; if (IsAquiferLayer(layer)) { - aquiferIndex = layerIndex; aquiferLayer = layer; - break; } - } - - // aquifer may consists of more then 1 connected (aquifer) layers - // Search all layers above the first found aquifer to find top aquifer layer - if (aquiferIndex >= 0) - { - for (int layerIndex = aquiferIndex + 1; layerIndex < sortedLayers.Count; layerIndex++) + else { - SoilLayer1D layer = sortedLayers[layerIndex]; - if (IsAquiferLayer(layer)) - { - aquiferLayer = layer; - } - else - { - break; - } + break; } } - - return aquiferLayer; } + + return aquiferLayer; } + } - /// - /// Gets the highest aquifer in the highest cluster of in-between aquifers. - /// The top layer of a cluster of in-between aquifer can't be the highest layer of the soil profile. - /// - /// - /// The highest aquifer in the highest in-between cluster of aquifers - /// - public SoilLayer1D InBetweenAquiferLayer + /// + /// Gets the highest aquifer in the highest cluster of in-between aquifers. + /// The top layer of a cluster of in-between aquifer can't be the highest layer of the soil profile. + /// + /// + /// The highest aquifer in the highest in-between cluster of aquifers + /// + public SoilLayer1D InBetweenAquiferLayer + { + get { - get - { - IList sortedLayers = Layers.OrderByDescending(l => l.TopLevel).ToList(); - SoilLayer1D aquiferLayer = null; + IList sortedLayers = Layers.OrderByDescending(l => l.TopLevel).ToList(); + SoilLayer1D aquiferLayer = null; - // Search the highest aquifer layer with an aquitard above - for (var layerIndex = 1; layerIndex < sortedLayers.Count; layerIndex++) + // Search the highest aquifer layer with an aquitard above + for (var layerIndex = 1; layerIndex < sortedLayers.Count; layerIndex++) + { + SoilLayer1D previousLayer = sortedLayers[layerIndex - 1]; + SoilLayer1D layer = sortedLayers[layerIndex]; + if (IsAquiferLayer(layer) && !IsAquiferLayer(previousLayer)) { - SoilLayer1D previousLayer = sortedLayers[layerIndex - 1]; - SoilLayer1D layer = sortedLayers[layerIndex]; - if (IsAquiferLayer(layer) && !IsAquiferLayer(previousLayer)) - { - aquiferLayer = layer; - break; - } + aquiferLayer = layer; + break; } - - // If highest aquifer layer is bottom aquifer layer, there is no in between aquiferlayer - if (aquiferLayer == BottomAquiferLayer) - { - aquiferLayer = null; - } - - return aquiferLayer; } - } - /// - /// Assigns the specified profile. - /// - /// The profile. - public void Assign(SoilProfile1D profile) - { - Assign((SoilProfile) profile); - Layers.Clear(); - foreach (SoilLayer1D layer in profile.Layers) + // If highest aquifer layer is bottom aquifer layer, there is no in between aquiferlayer + if (aquiferLayer == BottomAquiferLayer) { - Layers.Add((SoilLayer1D) layer.Clone()); + aquiferLayer = null; } - BottomLevel = profile.BottomLevel; + return aquiferLayer; } + } - /// - /// Creates a new object that is a copy of the current instance. - /// - /// - /// A new object that is a copy of this instance. - /// - public object Clone() + /// + /// Assigns the specified profile. + /// + /// The profile. + public void Assign(SoilProfile1D profile) + { + Assign((SoilProfile) profile); + Layers.Clear(); + foreach (SoilLayer1D layer in profile.Layers) { - var cloneSoilProfile = new SoilProfile1D(); - cloneSoilProfile.Assign(this); - return cloneSoilProfile; + Layers.Add((SoilLayer1D) layer.Clone()); } - /// - /// Gets layer with the specified name. - /// - /// The name. - /// - public SoilLayer1D GetLayerWithName(string name) + BottomLevel = profile.BottomLevel; + } + + /// + /// Creates a new object that is a copy of the current instance. + /// + /// + /// A new object that is a copy of this instance. + /// + public object Clone() + { + var cloneSoilProfile = new SoilProfile1D(); + cloneSoilProfile.Assign(this); + return cloneSoilProfile; + } + + /// + /// Gets layer with the specified name. + /// + /// The name. + /// + public SoilLayer1D GetLayerWithName(string name) + { + return layers.FirstOrDefault(layer => { - return layers.FirstOrDefault(layer => + if (layer.Name != null) { - if (layer.Name != null) - { - return layer.Name.Equals(name); - } + return layer.Name.Equals(name); + } - return false; - }); - } + return false; + }); + } - /// - /// Checks weather all layer names are unique. - /// - /// - /// true if all layer names are unique; otherwise, false. - /// - public bool AreAllLayerNamesUnique() + /// + /// Checks weather all layer names are unique. + /// + /// + /// true if all layer names are unique; otherwise, false. + /// + public bool AreAllLayerNamesUnique() + { + int layersSize = Layers.Count; + for (var i = 0; i < layersSize; ++i) { - int layersSize = Layers.Count; - for (var i = 0; i < layersSize; ++i) + string id1 = layers[i].Name; + if (id1 == null) { - string id1 = layers[i].Name; - if (id1 == null) + return false; + } + + for (int j = i + 1; j < layersSize; ++j) + { + if (id1.Equals(Layers[j].Name)) { return false; } - - for (int j = i + 1; j < layersSize; ++j) - { - if (id1.Equals(Layers[j].Name)) - { - return false; - } - } } - - return true; } - /// - /// Gets the first unused unique layer name. - /// - /// new unique layer name - public string GetNewUniqueLayerName() + return true; + } + + /// + /// Gets the first unused unique layer name. + /// + /// new unique layer name + public string GetNewUniqueLayerName() + { + string newName; + var i = 0; + SoilLayer1D soilLayer; + do { - string newName; - var i = 0; - SoilLayer1D soilLayer; - do - { - newName = "L" + i++; - soilLayer = GetLayerWithName(newName); - } while (soilLayer != null); + newName = "L" + i++; + soilLayer = GetLayerWithName(newName); + } while (soilLayer != null); - return newName; - } + return newName; + } - /// - /// Gets (calculates) the height for a given layer in the profile - /// - /// The layer to process - /// The height - public double GetLayerHeight(SoilLayer1D soilLayer) - { - int layerIndex = layers.IndexOf(soilLayer); - SoilLayer1D soilLayerBelow = (layerIndex < layers.Count - 1) ? layers[layerIndex + 1] : null; - double levelBelow = (soilLayerBelow != null) ? soilLayerBelow.TopLevel : BottomLevel; - return soilLayer.TopLevel - levelBelow; - } + /// + /// Gets (calculates) the height for a given layer in the profile + /// + /// The layer to process + /// The height + public double GetLayerHeight(SoilLayer1D soilLayer) + { + int layerIndex = layers.IndexOf(soilLayer); + SoilLayer1D soilLayerBelow = (layerIndex < layers.Count - 1) ? layers[layerIndex + 1] : null; + double levelBelow = (soilLayerBelow != null) ? soilLayerBelow.TopLevel : BottomLevel; + return soilLayer.TopLevel - levelBelow; + } - /// - /// Make sure the last layer has a height - /// - public void EnsureLastLayerHasHeight() + /// + /// Make sure the last layer has a height + /// + public void EnsureLastLayerHasHeight() + { + SoilLayer1D bottomLayer = Layers.Last(); + if (bottomLayer.Height.IsZero()) { - SoilLayer1D bottomLayer = Layers.Last(); - if (bottomLayer.Height.IsZero()) - { - BottomLevel -= DefaultBottomLayerHeight; - } + BottomLevel -= DefaultBottomLayerHeight; } + } - /// - /// Determines the infiltration layer. - /// - /// Length of the penetration. - public void DetermineInfiltrationLayer(double penetrationLength) - { - InfiltrationLayer = null; + /// + /// Determines the infiltration layer. + /// + /// Length of the penetration. + public void DetermineInfiltrationLayer(double penetrationLength) + { + InfiltrationLayer = null; - SoilLayer1D bottomAquiferLayer = BottomAquiferLayer; + SoilLayer1D bottomAquiferLayer = BottomAquiferLayer; - if (penetrationLength > 0 && bottomAquiferLayer != null) - { - SoilLayer1D inBetweenAquiferLayer = InBetweenAquiferLayer; + if (penetrationLength > 0 && bottomAquiferLayer != null) + { + SoilLayer1D inBetweenAquiferLayer = InBetweenAquiferLayer; - double aquiferBottom = inBetweenAquiferLayer == null ? Double.PositiveInfinity : inBetweenAquiferLayer.BottomLevel; + double aquiferBottom = inBetweenAquiferLayer == null ? Double.PositiveInfinity : inBetweenAquiferLayer.BottomLevel; - IList infiltrationLayers = - layers.Where(l => l.TopLevel <= aquiferBottom && l.TopLevel > bottomAquiferLayer.TopLevel) - .ToList(); + IList infiltrationLayers = + layers.Where(l => l.TopLevel <= aquiferBottom && l.TopLevel > bottomAquiferLayer.TopLevel) + .ToList(); - if (infiltrationLayers.Count > 0) - { - double separationLevel = bottomAquiferLayer.TopLevel + penetrationLength; + if (infiltrationLayers.Count > 0) + { + double separationLevel = bottomAquiferLayer.TopLevel + penetrationLength; - if (separationLevel <= infiltrationLayers.First().TopLevel) - { - InfiltrationLayer = layers.Last(l => l.TopLevel >= separationLevel); - } + if (separationLevel <= infiltrationLayers.First().TopLevel) + { + InfiltrationLayer = layers.Last(l => l.TopLevel >= separationLevel); } } } + } - /// - /// Validates this instance (using validator mechanism). - /// - /// - [Validate] - public ValidationResult[] Validate() - { - SoilLayer1D erroneousLayer; + /// + /// Validates this instance (using validator mechanism). + /// + /// + [Validate] + public ValidationResult[] Validate() + { + SoilLayer1D erroneousLayer; - if (LayerCount == 0) + if (LayerCount == 0) + { + string error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileWithoutLayers"), Name); + return new[] { - string error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileWithoutLayers"), Name); - return new[] - { - new ValidationResult(ValidationResultType.Error, - error, "", this) - }; - } + new ValidationResult(ValidationResultType.Error, + error, "", this) + }; + } - if (!IsStrictlyDescending(out erroneousLayer)) + if (!IsStrictlyDescending(out erroneousLayer)) + { + string error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileLayersNotDescending"), + Name, erroneousLayer.Name); + return new[] { - string error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileLayersNotDescending"), - Name, erroneousLayer.Name); - return new[] - { - new ValidationResult(ValidationResultType.Error, - error, "", this) - }; - } + new ValidationResult(ValidationResultType.Error, + error, "", this) + }; + } - if (HasInvalidThicknessLayers(out erroneousLayer)) + if (HasInvalidThicknessLayers(out erroneousLayer)) + { + string error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileInvalidLayerThickness"), + Name, erroneousLayer.Name); + return new[] { - string error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileInvalidLayerThickness"), - Name, erroneousLayer.Name); - return new[] - { - new ValidationResult(ValidationResultType.Error, - error, "", this) - }; - } - - if (HasLayersWithoutSoil(out erroneousLayer)) - { - string error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileLayerWithoutSoil"), - Name, erroneousLayer.Name); - return new[] - { - new ValidationResult(ValidationResultType.Error, - error, "", this) - }; - } - - return new ValidationResult[0]; + new ValidationResult(ValidationResultType.Error, + error, "", this) + }; } - /// - /// Gets the aquifer layers. - /// - /// list of Aquifer layers - public IList GetAquiferLayers() + if (HasLayersWithoutSoil(out erroneousLayer)) { - return Layers.Where(IsAquiferLayer).OrderBy(l => l.TopLevel).ToList(); + string error = String.Format(LocalizationManager.GetTranslatedText(this, "SoilProfileLayerWithoutSoil"), + Name, erroneousLayer.Name); + return new[] + { + new ValidationResult(ValidationResultType.Error, + error, "", this) + }; } - /// - /// Gets the bottom level. - /// - /// The soil layer. - /// Bottom level - public double GetBottomLevel(SoilLayer1D soilLayer) - { - SoilLayer1D layerBelow = GetLayerBelow(soilLayer); + return new ValidationResult[0]; + } - return layerBelow != null ? layerBelow.TopLevel : BottomLevel; - } + /// + /// Gets the aquifer layers. + /// + /// list of Aquifer layers + public IList GetAquiferLayers() + { + return Layers.Where(IsAquiferLayer).OrderBy(l => l.TopLevel).ToList(); + } - /// - /// Gets the layer at a given z coordinate. - /// - /// The z. - /// the found layer - public SoilLayer1D GetLayerAt(double z) - { - return Layers.FirstOrDefault(soilLayer => soilLayer.BottomLevel < z && soilLayer.TopLevel >= z); - } + /// + /// Gets the bottom level. + /// + /// The soil layer. + /// Bottom level + public double GetBottomLevel(SoilLayer1D soilLayer) + { + SoilLayer1D layerBelow = GetLayerBelow(soilLayer); - /// - /// Gets the layer below the given layer. - /// - /// The given layer. - /// The found layer - public SoilLayer1D GetLayerBelow(SoilLayer1D layer) - { - return GetLayerByInsetOffset(layer, 1); - } + return layerBelow != null ? layerBelow.TopLevel : BottomLevel; + } - /// - /// Gets the layer index of the given layer. - /// - /// The layer. - /// The index, -1 if not found - public int GetLayerIndexAt(SoilLayer1D layer) - { - if (layer == null) - { - return -1; - } + /// + /// Gets the layer at a given z coordinate. + /// + /// The z. + /// the found layer + public SoilLayer1D GetLayerAt(double z) + { + return Layers.FirstOrDefault(soilLayer => soilLayer.BottomLevel < z && soilLayer.TopLevel >= z); + } - for (var i = 0; i < layers.Count; ++i) - { - if (layers[i] == layer) - { - return i; - } - } + /// + /// Gets the layer below the given layer. + /// + /// The given layer. + /// The found layer + public SoilLayer1D GetLayerBelow(SoilLayer1D layer) + { + return GetLayerByInsetOffset(layer, 1); + } + /// + /// Gets the layer index of the given layer. + /// + /// The layer. + /// The index, -1 if not found + public int GetLayerIndexAt(SoilLayer1D layer) + { + if (layer == null) + { return -1; } - /// - /// Gets the top level of highest aquifer. - /// - /// - public double GetTopLevelOfHighestAquifer() + for (var i = 0; i < layers.Count; ++i) { - double topLevel; - if (InBetweenAquiferLayer != null) + if (layers[i] == layer) { - topLevel = InBetweenAquiferLayer.TopLevel; + return i; } - else - { - topLevel = BottomAquiferLayer.TopLevel; - } - - return topLevel; } - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() + return -1; + } + + /// + /// Gets the top level of highest aquifer. + /// + /// + public double GetTopLevelOfHighestAquifer() + { + double topLevel; + if (InBetweenAquiferLayer != null) { - return Name; + topLevel = InBetweenAquiferLayer.TopLevel; } - - /// - /// Ares the layers ordered descending. - /// - /// - /// true if all layers are ordered descending; otherwise, false. - /// - private bool AreLayersOrderedByDescending() + else { - // check for empty list - if (Layers.Count <= 1) - { - return true; - } + topLevel = BottomAquiferLayer.TopLevel; + } - SoilLayer1D current = Layers[0]; - for (var i = 1; i < Layers.Count; ++i) - { - SoilLayer1D previous = current; - current = Layers[i]; + return topLevel; + } - if (current.TopLevel > previous.TopLevel) - { - return false; - } - } + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return Name; + } + /// + /// Ares the layers ordered descending. + /// + /// + /// true if all layers are ordered descending; otherwise, false. + /// + private bool AreLayersOrderedByDescending() + { + // check for empty list + if (Layers.Count <= 1) + { return true; } - /// - /// Determines whether the layers are strictly ordered in descending order. - /// If erroneous layer is found, false is returned and the layer - /// is stored in the parameter - /// - /// The erroneous layer. - /// true if the layers are strictly ordered in descending order; otherwise, false. - private bool IsStrictlyDescending(out SoilLayer1D erroneousLayer) + SoilLayer1D current = Layers[0]; + for (var i = 1; i < Layers.Count; ++i) { - for (var i = 1; i < layers.Count; i++) + SoilLayer1D previous = current; + current = Layers[i]; + + if (current.TopLevel > previous.TopLevel) { - if (layers[i].TopLevel > layers[i - 1].TopLevel) - { - erroneousLayer = layers[i]; - return false; - } + return false; } - - erroneousLayer = null; - return true; } - /// - /// Determines whether there are layers with invalid thickness. - /// - /// The erroneous layer. - /// True when a layer with invalid thickness exists - private bool HasInvalidThicknessLayers(out SoilLayer1D erroneousLayer) + return true; + } + + /// + /// Determines whether the layers are strictly ordered in descending order. + /// If erroneous layer is found, false is returned and the layer + /// is stored in the parameter + /// + /// The erroneous layer. + /// true if the layers are strictly ordered in descending order; otherwise, false. + private bool IsStrictlyDescending(out SoilLayer1D erroneousLayer) + { + for (var i = 1; i < layers.Count; i++) { - for (var i = 1; i < layers.Count; i++) + if (layers[i].TopLevel > layers[i - 1].TopLevel) { - if (layers[i].TopLevel >= layers[i - 1].TopLevel) - { - erroneousLayer = layers[i]; - return true; - } + erroneousLayer = layers[i]; + return false; } + } - // check bottom layer using bottom of profile - if (layers.Count > 0 && layers[layers.Count - 1].TopLevel <= BottomLevel) + erroneousLayer = null; + return true; + } + + /// + /// Determines whether there are layers with invalid thickness. + /// + /// The erroneous layer. + /// True when a layer with invalid thickness exists + private bool HasInvalidThicknessLayers(out SoilLayer1D erroneousLayer) + { + for (var i = 1; i < layers.Count; i++) + { + if (layers[i].TopLevel >= layers[i - 1].TopLevel) { - erroneousLayer = layers[layers.Count - 1]; + erroneousLayer = layers[i]; return true; } - - erroneousLayer = null; - return false; } - /// - /// Determines whether there are layers without soil. - /// - /// The erroneous layer. - /// true when a layer without soil is found - private bool HasLayersWithoutSoil(out SoilLayer1D erroneousLayer) + // check bottom layer using bottom of profile + if (layers.Count > 0 && layers[layers.Count - 1].TopLevel <= BottomLevel) { - for (var i = 0; i < layers.Count; i++) - { - if (layers[i].Soil == null) - { - erroneousLayer = layers[i]; - return true; - } - } - - erroneousLayer = null; - return false; + erroneousLayer = layers[layers.Count - 1]; + return true; } - /// - /// Gets the layer by inset offset, seen from the given layer plus the given offset. - /// - /// The layer. - /// The offset. - /// the found layer, if no layer found, null - private SoilLayer1D GetLayerByInsetOffset(SoilLayer1D layer, int offset) + erroneousLayer = null; + return false; + } + + /// + /// Determines whether there are layers without soil. + /// + /// The erroneous layer. + /// true when a layer without soil is found + private bool HasLayersWithoutSoil(out SoilLayer1D erroneousLayer) + { + for (var i = 0; i < layers.Count; i++) { - // only works if list is sorted - if (!AreLayersOrderedByDescending()) + if (layers[i].Soil == null) { - layers.Sort(); + erroneousLayer = layers[i]; + return true; } + } - int index = GetLayerIndexAt(layer); + erroneousLayer = null; + return false; + } - // was the layer found? - if (index < 0 || index >= layers.Count) - { - return null; - } - - // is there a layer at the specified offset? - int requestedIndex = index + offset; - if (requestedIndex < 0 || requestedIndex >= layers.Count) - { - return null; - } - - // return the valid layer - return layers[requestedIndex]; + /// + /// Gets the layer by inset offset, seen from the given layer plus the given offset. + /// + /// The layer. + /// The offset. + /// the found layer, if no layer found, null + private SoilLayer1D GetLayerByInsetOffset(SoilLayer1D layer, int offset) + { + // only works if list is sorted + if (!AreLayersOrderedByDescending()) + { + layers.Sort(); } - private void AddLayer(SoilLayer1D layer) + int index = GetLayerIndexAt(layer); + + // was the layer found? + if (index < 0 || index >= layers.Count) { - layer.SoilProfile = this; + return null; } - /// - /// Determines whether the specified layer is an aquifer layer. - /// - /// The layer. - /// true if layer is aquifer layer; otherwise, false. - private static bool IsAquiferLayer(SoilLayer1D layer) + // is there a layer at the specified offset? + int requestedIndex = index + offset; + if (requestedIndex < 0 || requestedIndex >= layers.Count) { - return (layer.IsAquifer); + return null; } + + // return the valid layer + return layers[requestedIndex]; } + + private void AddLayer(SoilLayer1D layer) + { + layer.SoilProfile = this; + } + + /// + /// Determines whether the specified layer is an aquifer layer. + /// + /// The layer. + /// true if layer is aquifer layer; otherwise, false. + private static bool IsAquiferLayer(SoilLayer1D layer) + { + return (layer.IsAquifer); + } } \ No newline at end of file