Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs =================================================================== diff -u -r6087 -r6404 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs (.../SoilProfile2D.cs) (revision 6087) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs (.../SoilProfile2D.cs) (revision 6404) @@ -1,4 +1,4 @@ -// Copyright (C) Stichting Deltares 2024. All rights reserved. +// Copyright (C) Stichting Deltares 2025. All rights reserved. // // This file is part of the Dam Engine. // @@ -34,10 +34,10 @@ /// public class SoilProfile2D : SoilProfile { - private readonly List surfaces = new List(); private const double deviation = 1E-05; private const double toleranceAlmostEqual = 1e-07; - + private readonly List surfaces = new List(); + /// /// Initializes a new instance of the class. /// @@ -68,7 +68,7 @@ /// The geometry. /// public GeometryData Geometry { get; set; } = new GeometryData(); - + /// /// Gets the soil profile 1D at the given X. /// If the given X coincides with a vertical layer separation and both profiles at left and at right of the separation @@ -84,7 +84,7 @@ Geometry.Right = Geometry.MaxGeometryPointsX; Geometry.Left = Geometry.MinGeometryPointsX; } - + // At the end of a geometry, there are no layers to be found beyond that end. In that case get the layers just before // the end of the geometry. if (x.IsGreaterThanOrEqualTo(Geometry.Right, toleranceAlmostEqual)) @@ -96,7 +96,7 @@ { x = Geometry.Left + diff; } - + bool isXShiftedToRight; double xRelevant = x; do @@ -106,7 +106,6 @@ { xRelevant += diff; } - } while (isXShiftedToRight && xRelevant < Geometry.Right); return DetermineSoilProfile1DAtX(xRelevant); @@ -121,46 +120,37 @@ var clonedSoilProfile2D = new SoilProfile2D { Name = Name - }; clonedSoilProfile2D.Geometry = Geometry.Clone(); foreach (SoilLayer2D surface in Surfaces) { SoilLayer2D clonedSurface = surface.Clone(clonedSoilProfile2D.Geometry); clonedSoilProfile2D.Surfaces.Add(clonedSurface); } + foreach (PreConsolidationStress preconsolidationStress in PreconsolidationStresses) { - clonedSoilProfile2D.PreconsolidationStresses.Add((PreConsolidationStress)preconsolidationStress.Clone()); + clonedSoilProfile2D.PreconsolidationStresses.Add((PreConsolidationStress) preconsolidationStress.Clone()); } + return clonedSoilProfile2D; } /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return Name; - } - - /// /// Finds a SoilLayer2D based on its outer loop /// /// /// the layer or when not found null public SoilLayer2D FindSoilLayer2DByItsOuterLoop(GeometryLoop outerLoop) { foreach (SoilLayer2D soilLayer2D in Surfaces) - { + { if (soilLayer2D.GeometrySurface.OuterLoop.HasSameCurves(outerLoop)) { return soilLayer2D; - } + } } + return null; } @@ -170,19 +160,20 @@ /// /// /// The 2D soil layer - public static SoilLayer2D DetermineOriginalLayerFromOldSurfaces(GeometrySurface geometrySurface, + public static SoilLayer2D DetermineOriginalLayerFromOldSurfaces(GeometrySurface geometrySurface, IEnumerable oldSurfaces) { - Point2D point = new Point2D(0.0, 0.0); - bool isPointInOuterLoopAndOldSurface = false; + var point = new Point2D(0.0, 0.0); + var isPointInOuterLoopAndOldSurface = false; point = IsPointInOuterLoopAndOldSurface(geometrySurface, oldSurfaces, point, ref isPointInOuterLoopAndOldSurface); - + if (!isPointInOuterLoopAndOldSurface) { - isPointInOuterLoopAndOldSurface = IsPointInOldSurfaceJustBelowTopOfNewGeometryWithinItsLimits(geometrySurface, - oldSurfaces, point, + isPointInOuterLoopAndOldSurface = IsPointInOldSurfaceJustBelowTopOfNewGeometryWithinItsLimits(geometrySurface, + oldSurfaces, point, isPointInOuterLoopAndOldSurface); } + if (isPointInOuterLoopAndOldSurface) { if (IsPointInPreviousOuterLoopOfOldSurface(oldSurfaces, point, out SoilLayer2D soilLayer2D)) @@ -195,25 +186,40 @@ return originalLayerFromOldSurfaces1; } } + return null; } - private static bool IsPointInOuterLoopOfOldSurface(IEnumerable oldSurfaces, Point2D point, + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return Name; + } + + private static bool IsPointInOuterLoopOfOldSurface(IEnumerable oldSurfaces, Point2D point, out SoilLayer2D originalLayerFromOldSurfaces1) { originalLayerFromOldSurfaces1 = null; foreach (SoilLayer2D oldSurface in oldSurfaces) { GeometryLoop outerLoop = oldSurface.GeometrySurface.OuterLoop; - if (outerLoop != null && outerLoop.CurveList.Count > 2 && Routines2D.CheckIfPointIsInPolygon(outerLoop, point.X, + if (outerLoop != null && outerLoop.CurveList.Count > 2 && Routines2D.CheckIfPointIsInPolygon(outerLoop, point.X, point.Z) == PointInPolygon.InsidePolygon) { - bool isPointInOuterLoopOfOldSurface = true; + var isPointInOuterLoopOfOldSurface = true; foreach (GeometryLoop innerLoop in oldSurface.GeometrySurface.InnerLoops) { if (Routines2D.CheckIfPointIsInPolygon(innerLoop, point.X, point.Z) == PointInPolygon.InsidePolygon) + { isPointInOuterLoopOfOldSurface = false; + } } + if (isPointInOuterLoopOfOldSurface) { originalLayerFromOldSurfaces1 = oldSurface; @@ -225,22 +231,25 @@ return false; } - private static bool IsPointInPreviousOuterLoopOfOldSurface(IEnumerable oldSurfaces, Point2D point, + private static bool IsPointInPreviousOuterLoopOfOldSurface(IEnumerable oldSurfaces, Point2D point, out SoilLayer2D soilLayer2D) { soilLayer2D = null; foreach (SoilLayer2D oldSurface in oldSurfaces) { GeometryLoop previousOuterLoop = oldSurface.GeometrySurface.PreviousOuterLoop; - if (previousOuterLoop != null && previousOuterLoop.CurveList.Count > 2 && + if (previousOuterLoop != null && previousOuterLoop.CurveList.Count > 2 && Routines2D.CheckIfPointIsInPolygon(previousOuterLoop, point.X, point.Z) == PointInPolygon.InsidePolygon) { - bool isPointInPreviousOuterLoopOfOldSurface = true; + var isPointInPreviousOuterLoopOfOldSurface = true; foreach (GeometryLoop previousInnerLoop in oldSurface.GeometrySurface.PreviousInnerLoops) { if (Routines2D.CheckIfPointIsInPolygon(previousInnerLoop, point.X, point.Z) == PointInPolygon.InsidePolygon) + { isPointInPreviousOuterLoopOfOldSurface = false; + } } + if (isPointInPreviousOuterLoopOfOldSurface) { soilLayer2D = oldSurface; @@ -252,15 +261,15 @@ return false; } - private static bool IsPointInOldSurfaceJustBelowTopOfNewGeometryWithinItsLimits(GeometrySurface geometrySurface, + private static bool IsPointInOldSurfaceJustBelowTopOfNewGeometryWithinItsLimits(GeometrySurface geometrySurface, IEnumerable oldSurfaces, Point2D point, bool isPointInOuterLoopAndOldSurface) { GeometryPointString topGeometrySurface = geometrySurface.DetermineTopGeometrySurface(); topGeometrySurface.SortPointsByXAscending(); Point2D geometryPoint1 = topGeometrySurface[0]; geometryPoint1.X -= deviation; geometryPoint1.Z -= deviation; - Point2D geometryPoint2 = topGeometrySurface[checked (topGeometrySurface.Count - 1)]; + Point2D geometryPoint2 = topGeometrySurface[checked(topGeometrySurface.Count - 1)]; geometryPoint2.X += deviation; geometryPoint2.Z -= deviation; bool isPoint1WithinOldSurfaces = IsPointWithinOldSurfaces(geometryPoint1, oldSurfaces, -deviation); @@ -273,19 +282,23 @@ isPointInOuterLoopAndOldSurface = true; d = geometryPoint1.X + deviation; } + if (!isPoint1WithinOldSurfaces && isPoint2WithinOldSurfaces) { point.X = geometryPoint2.X; point.Z = geometryPoint2.Z; isPointInOuterLoopAndOldSurface = true; d = geometryPoint2.X - deviation; } + if (!double.IsNaN(d)) { double xminFromSurfaces = DetermineXminFromSurfaces(oldSurfaces); double xmaxFromSurfaces = DetermineXmaxFromSurfaces(oldSurfaces); if (d <= xmaxFromSurfaces && d >= xminFromSurfaces) + { isPointInOuterLoopAndOldSurface = false; + } } return isPointInOuterLoopAndOldSurface; @@ -296,18 +309,19 @@ foreach (GeometryCurve curve in geometrySurface.OuterLoop.CurveList) { point = new Point2D((curve.HeadPoint.X + curve.EndPoint.X) / 2.0, (curve.HeadPoint.Z + curve.EndPoint.Z) / 2.0); - if (IsPointWithinOldSurfaces(point, oldSurfaces, deviation) || IsPointWithinOldSurfaces(point, oldSurfaces, - -deviation)) + if (IsPointWithinOldSurfaces(point, oldSurfaces, deviation) || IsPointWithinOldSurfaces(point, oldSurfaces, + -deviation)) { point.Z += deviation; - if (Routines2D.CheckIfPointIsInPolygon(geometrySurface.OuterLoop, point.X, point.Z) == + if (Routines2D.CheckIfPointIsInPolygon(geometrySurface.OuterLoop, point.X, point.Z) == PointInPolygon.InsidePolygon) { isPointInOuterLoopAndOldSurface = true; break; } - point.Z -= 2*deviation; - if (Routines2D.CheckIfPointIsInPolygon(geometrySurface.OuterLoop, point.X, point.Z) == + + point.Z -= 2 * deviation; + if (Routines2D.CheckIfPointIsInPolygon(geometrySurface.OuterLoop, point.X, point.Z) == PointInPolygon.InsidePolygon) { isPointInOuterLoopAndOldSurface = true; @@ -321,20 +335,26 @@ private static double DetermineXminFromSurfaces(IEnumerable oldSurfaces) { - double xminFromSurfaces = double.MaxValue; + var xminFromSurfaces = double.MaxValue; foreach (SoilLayer2D oldSurface in oldSurfaces) + { xminFromSurfaces = Math.Min(xminFromSurfaces, oldSurface.GeometrySurface.OuterLoop.GetMinX()); + } + return xminFromSurfaces; } private static double DetermineXmaxFromSurfaces(IEnumerable oldSurfaces) { - double xmaxFromSurfaces = double.MinValue; + var xmaxFromSurfaces = double.MinValue; foreach (SoilLayer2D oldSurface in oldSurfaces) + { xmaxFromSurfaces = Math.Max(xmaxFromSurfaces, oldSurface.GeometrySurface.OuterLoop.GetMaxX()); + } + return xmaxFromSurfaces; } - + private static bool IsPointWithinOldSurfaces(Point2D point, IEnumerable oldSurfaces, double verticalShift) { point.Z += verticalShift; @@ -343,21 +363,24 @@ { GeometryLoop outerLoop = oldSurface.GeometrySurface.OuterLoop; List innerLoops = oldSurface.GeometrySurface.InnerLoops; - var isPointInSurface = IsPointInGivenOuterLoopOfOldSurface(shiftedPoint, outerLoop, innerLoops); + bool isPointInSurface = IsPointInGivenOuterLoopOfOldSurface(shiftedPoint, outerLoop, innerLoops); if (!isPointInSurface) { GeometryLoop previousOuterLoop = oldSurface.GeometrySurface.PreviousOuterLoop; List previousInnerLoops = oldSurface.GeometrySurface.PreviousInnerLoops; isPointInSurface = IsPointInGivenOuterLoopOfOldSurface(shiftedPoint, previousOuterLoop, previousInnerLoops); } + if (isPointInSurface) + { return true; + } } + return false; } - - private static bool IsPointInGivenOuterLoopOfOldSurface(Point2D point, GeometryLoop outerLoop, + private static bool IsPointInGivenOuterLoopOfOldSurface(Point2D point, GeometryLoop outerLoop, List innerLoops) { var isPointInSurface = false; @@ -368,9 +391,12 @@ foreach (GeometryLoop innerLoop in innerLoops) { if (Routines2D.CheckIfPointIsInPolygon(innerLoop, point.X, point.Z) == PointInPolygon.InsidePolygon) + { return false; + } } } + return isPointInSurface; } @@ -406,15 +432,15 @@ private bool AreLayersWithVerticalPartPresentAtGivenX(double xCoordinate) { return Surfaces.Any(surface => surface.GeometrySurface.OuterLoop.CurveList.Any - (curve => curve.HeadPoint.X.IsNearEqual(xCoordinate, toleranceAlmostEqual) && + (curve => curve.HeadPoint.X.IsNearEqual(xCoordinate, toleranceAlmostEqual) && curve.EndPoint.X.IsNearEqual(xCoordinate, toleranceAlmostEqual))); } - + private bool AreSoilProfilesIdentical(double x1, double x2) { SoilProfile1D soilProfile1 = DetermineSoilProfile1DAtX(x1); SoilProfile1D soilProfile2 = DetermineSoilProfile1DAtX(x2); - + bool isIdentical = soilProfile1.Layers.Count == soilProfile2.Layers.Count; if (!isIdentical) {