Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelper.cs =================================================================== diff -u -r5847 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelper.cs (.../MacroStabilityCommonHelper.cs) (revision 5847) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelper.cs (.../MacroStabilityCommonHelper.cs) (revision 5863) @@ -63,15 +63,15 @@ /// Thrown when subSoilScenario.SoilProfileType is ProfileTypeStiFile /// /// The combined profile as full SoilProfile2D - public static SoilProfile2D CombineSoilProfileWithSurfaceLine(SoilGeometryProbability subSoilScenario, SurfaceLine2 surfaceLine2, Soil dikeEmbankmentSoil) + public static SoilProfile2D CombineSoilProfileWithSurfaceLine(SoilGeometryProbability subSoilScenario, SurfaceLine2 surfaceLine2, Soil dikeEmbankmentSoil, double shift) { switch (subSoilScenario.SoilProfileType) { case SoilProfileType.ProfileType1D: CombineSoilProfile1DWithSurfaceLine(subSoilScenario, surfaceLine2, dikeEmbankmentSoil); break; case SoilProfileType.ProfileType2D: - CombineSoilProfile2DWithSurfaceLine(subSoilScenario, surfaceLine2, dikeEmbankmentSoil); + CombineSoilProfile2DWithSurfaceLine(subSoilScenario, surfaceLine2, dikeEmbankmentSoil, shift); break; default: throw new NotImplementedException(); @@ -450,11 +450,11 @@ /// The required shift of the geometry so it will fit the surface line. /// Thrown when no SoilProfile2D is defined private static void CombineSoilProfile2DWithSurfaceLine(SoilGeometryProbability subSoilScenario, SurfaceLine2 surfaceLine2, - Soil dikeEmbankmentSoil) + Soil dikeEmbankmentSoil, double shift) { ValidateForCombineSoilProfile2DWithSurfaceLine(subSoilScenario, surfaceLine2, dikeEmbankmentSoil); - subSoilScenario.SoilProfile2D = SoilProfile2DSurfaceLineHelper.CombineSurfaceLineWithSoilProfile2D(surfaceLine2.Geometry, subSoilScenario.SoilProfile2D, dikeEmbankmentSoil); + subSoilScenario.SoilProfile2D = SoilProfile2DSurfaceLineHelper.CombineSurfaceLineWithSoilProfile2D(surfaceLine2.Geometry, subSoilScenario.SoilProfile2D, dikeEmbankmentSoil, shift); } private static void ValidateForCombineSoilProfile2DWithSurfaceLine(SoilGeometryProbability subSoilScenario, SurfaceLine2 surfaceLine2, Soil dikeEmbankmentSoil) Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs =================================================================== diff -u -r5847 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs (.../SoilProfile2D.cs) (revision 5847) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs (.../SoilProfile2D.cs) (revision 5863) @@ -152,22 +152,23 @@ /// /// /// + /// /// The 2D soil layer - public static SoilLayer2D DetermineOriginalLayerFromOldSurfaces(GeometrySurface geometrySurface, - IEnumerable oldSurfaces) + public static SoilLayer2D DetermineOriginalLayerFromOldSurfaces(GeometrySurface geometrySurface, IEnumerable oldSurfaces, + double shift) { Point2D point = new Point2D(0.0, 0.0); bool isPointInOuterLoopAndOldSurface = false; - point = IsPointInOuterLoopAndOldSurface(geometrySurface, oldSurfaces, point, ref isPointInOuterLoopAndOldSurface); + point = IsPointInOuterLoopAndOldSurface(geometrySurface, oldSurfaces, shift, point, ref isPointInOuterLoopAndOldSurface); if (!isPointInOuterLoopAndOldSurface) { isPointInOuterLoopAndOldSurface = IsPointInOldSurfaceJustBelowTopOfNewGeometryWithinItsLimits(geometrySurface, - oldSurfaces, point, - isPointInOuterLoopAndOldSurface); + oldSurfaces, shift, point, isPointInOuterLoopAndOldSurface); } if (isPointInOuterLoopAndOldSurface) { + point.X -= shift; if (IsPointInPreviousOuterLoopOfOldSurface(oldSurfaces, point, out SoilLayer2D soilLayer2D)) { return soilLayer2D; @@ -236,7 +237,7 @@ } private static bool IsPointInOldSurfaceJustBelowTopOfNewGeometryWithinItsLimits(GeometrySurface geometrySurface, - IEnumerable oldSurfaces, Point2D point, bool isPointInOuterLoopAndOldSurface) + IEnumerable oldSurfaces, double shift, Point2D point, bool isPointInOuterLoopAndOldSurface) { GeometryPointString topGeometrySurface = geometrySurface.DetermineTopGeometrySurface(); topGeometrySurface.SortPointsByXAscending(); @@ -246,8 +247,8 @@ Point2D geometryPoint2 = topGeometrySurface[checked (topGeometrySurface.Count - 1)]; geometryPoint2.X += deviation; geometryPoint2.Z -= deviation; - bool isPoint1WithinOldSurfaces = IsPointWithinOldSurfaces(geometryPoint1, oldSurfaces, -deviation); - bool isPoint2WithinOldSurfaces = IsPointWithinOldSurfaces(geometryPoint2, oldSurfaces, -deviation); + bool isPoint1WithinOldSurfaces = IsPointWithinOldSurfaces(geometryPoint1, oldSurfaces, shift, -deviation); + bool isPoint2WithinOldSurfaces = IsPointWithinOldSurfaces(geometryPoint2, oldSurfaces, shift, -deviation); double d = double.NaN; if (isPoint1WithinOldSurfaces && !isPoint2WithinOldSurfaces) { @@ -274,13 +275,13 @@ return isPointInOuterLoopAndOldSurface; } - private static Point2D IsPointInOuterLoopAndOldSurface(GeometrySurface geometrySurface, IEnumerable oldSurfaces, Point2D point, ref bool isPointInOuterLoopAndOldSurface) + private static Point2D IsPointInOuterLoopAndOldSurface(GeometrySurface geometrySurface, IEnumerable oldSurfaces, double shift, Point2D point, ref bool isPointInOuterLoopAndOldSurface) { 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, shift, deviation) || IsPointWithinOldSurfaces(point, oldSurfaces, + shift, -deviation)) { point.Z += deviation; if (Routines2D.CheckIfPointIsInPolygon(geometrySurface.OuterLoop, point.X, point.Z) == @@ -318,10 +319,11 @@ return xmaxFromSurfaces; } - private static bool IsPointWithinOldSurfaces(Point2D point, IEnumerable oldSurfaces, double verticalShift) + private static bool IsPointWithinOldSurfaces(Point2D point, IEnumerable oldSurfaces, double shift, + double verticalShift) { point.Z += verticalShift; - var shiftedPoint = new Point2D(point.X, point.Z); + var shiftedPoint = new Point2D(point.X - shift, point.Z); foreach (SoilLayer2D oldSurface in oldSurfaces) { GeometryLoop outerLoop = oldSurface.GeometrySurface.OuterLoop; Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityInwards/MacroStabilityInwardsKernelWrapper.cs =================================================================== diff -u -r5847 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityInwards/MacroStabilityInwardsKernelWrapper.cs (.../MacroStabilityInwardsKernelWrapper.cs) (revision 5847) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityInwards/MacroStabilityInwardsKernelWrapper.cs (.../MacroStabilityInwardsKernelWrapper.cs) (revision 5863) @@ -111,7 +111,7 @@ } MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(damKernelInput.SubSoilScenario, damKernelInput.Location.SurfaceLine, - damKernelInput.CurrentEmbankmentSoil); + damKernelInput.CurrentEmbankmentSoil, damKernelInput.Location.XSoilGeometry2DOrigin); const bool useRiverLevelLow = false; // Determine whether there is uplift Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2DSurfaceLineHelper.cs =================================================================== diff -u -r5847 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2DSurfaceLineHelper.cs (.../SoilProfile2DSurfaceLineHelper.cs) (revision 5847) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilProfile2DSurfaceLineHelper.cs (.../SoilProfile2DSurfaceLineHelper.cs) (revision 5863) @@ -68,9 +68,10 @@ /// The surface line. /// The SoilProfile2D. /// The dike embankment soil. + /// The required shift of the geometry so it will fit the surface line. /// public static SoilProfile2D CombineSurfaceLineWithSoilProfile2D(GeometryPointString surfaceLine, SoilProfile2D soilProfile2D, - Soil defaultSoil) + Soil defaultSoil, double shift) { if (soilProfile2D == null || soilProfile2D.Surfaces.Count == 0) return null; @@ -79,26 +80,37 @@ SoilProfile2D clonedProfile = soilProfile2D.Clone(); GeometryPointString clonedSurfaceLine = surfaceLine.Clone(); - - RoundCoordinates(clonedProfile.Geometry); + GeometryPointString originalSurfaceLine = soilProfile2D.Geometry.SurfaceLine; + shift = GeometryObject.RoundValue(shift); + if (Math.Abs(shift) >= GeometryConstants.Accuracy) + { + foreach (Point2D point in clonedProfile.Geometry.Points) + point.X += shift; + clonedProfile.Geometry.Rebox(); + + foreach (GeometryPoint point in originalSurfaceLine.Points) + point.X += shift; + originalSurfaceLine.SyncCalcPoints(); + } + if (clonedProfile.Geometry.Right < surfaceLine.GetMinX() || clonedProfile.Geometry.Left > surfaceLine.GetMaxX()) { throw new ArgumentException("Surface line is beyond the profile."); } - // As the original profile may have been moved as cloned profile, a new clone is needed to perform all reset actions with. // The cloned profile is used to determine the original surfaces and preconsolidations. - //SoilProfile2D soilProfile2D2 = clonedProfile.Clone(); + SoilProfile2D soilProfile2D2 = clonedProfile.Clone(); + var oldSurfaces = new List(); - oldSurfaces.AddRange((IEnumerable) soilProfile2D.Surfaces); + oldSurfaces.AddRange((IEnumerable) soilProfile2D2.Surfaces); var result = new SoilProfile2D(); result.Name = soilProfile2D.Name; result.Geometry = CreateNewGeometryForSoilProfile2DByCombiningItsGeometryWithSurfaceLine(clonedSurfaceLine, clonedProfile.Geometry); RemoveGeometryDataOfSoilProfileAboveSurfaceLine(clonedSurfaceLine, ref result); - ReconstructSurfaces(ref result, clonedSurfaceLine, oldSurfaces, defaultSoil); - ReconstructPreConsolidations(ref result, clonedProfile); + ReconstructSurfaces(ref result, originalSurfaceLine, oldSurfaces, defaultSoil, shift); + ReconstructPreConsolidations(ref result, clonedProfile, shift); result.Geometry.Rebox(); result.Geometry.UpdateSurfaceLine(); RoundCoordinates(result.Geometry); @@ -303,8 +315,8 @@ result.DeleteLoosePoints(); } - private static void ReconstructSurfaces(ref SoilProfile2D result, GeometryPointString surfaceLine, - List oldSurfaces, Soil defaultSoil) + private static void ReconstructSurfaces(ref SoilProfile2D result, GeometryPointString surfaceLine, List oldSurfaces, + Soil defaultSoil, double shift) { result.Surfaces.Clear(); foreach (GeometrySurface surface in result.Geometry.Surfaces) @@ -315,7 +327,7 @@ Soil = defaultSoil }; SoilLayer2D soilLayer2D2 = soilLayer2D1; - SoilLayer2D layerFromOldSurfaces = SoilProfile2D.DetermineOriginalLayerFromOldSurfaces(surface, oldSurfaces); + SoilLayer2D layerFromOldSurfaces = SoilProfile2D.DetermineOriginalLayerFromOldSurfaces(surface, (IEnumerable) oldSurfaces, shift); if (layerFromOldSurfaces != null && layerFromOldSurfaces.Soil != null) { soilLayer2D2.Soil = layerFromOldSurfaces.Soil; @@ -329,7 +341,7 @@ bool isDefaultLayer = IsLayerAboveOriginalSurfaceLine(soilLayer2D2, surfaceLine); if (!isDefaultLayer) { - oldLayer = DetermineLayerIfSurfaceIsLeftOrRightOfOldSurfaces(surface, oldSurfaces); + oldLayer = DetermineLayerIfSurfaceIsLeftOrRightOfOldSurfaces(surface, oldSurfaces, shift); isDefaultLayer = oldLayer == null; } if (!isDefaultLayer) @@ -361,21 +373,22 @@ return layer.GeometrySurface.OuterLoop.Points.All(point => !point.Z.IsLessThan(surfaceLine.GetZatX(point.X))); } - private static void ReconstructPreConsolidations(ref SoilProfile2D result, SoilProfile2D clonedProfile) + private static void ReconstructPreConsolidations(ref SoilProfile2D result, SoilProfile2D clonedProfile, double shift) { foreach (PreConsolidationStress preconsolidationStress in clonedProfile.PreconsolidationStresses) { + preconsolidationStress.X += shift; result.PreconsolidationStresses.Add(preconsolidationStress); } } - private static SoilLayer2D DetermineLayerIfSurfaceIsLeftOrRightOfOldSurfaces(GeometrySurface surface, List oldSurfaces) + private static SoilLayer2D DetermineLayerIfSurfaceIsLeftOrRightOfOldSurfaces(GeometrySurface surface, List oldSurfaces, double shift) { double[] xMin = surface.OuterLoop.CalcPoints.Select(p => p.X).OrderBy(x => x).Distinct().ToArray(); double[] zMin = surface.OuterLoop.CalcPoints.Select(p => p.Z).OrderBy(z => z).Distinct().ToArray(); var leftPoint = new Point2D { - X = xMin[0] - 0.1, + X = xMin[0] - shift - 0.1, Z = zMin[0] + 0.1 }; @@ -387,7 +400,7 @@ var rightPoint = new Point2D { - X = xMin[^1] + 0.1, + X = xMin[^1] - shift + 0.1, Z = zMin[0] + 0.1 }; Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorCombinedSlopeAndShoulderAdaption.cs =================================================================== diff -u -r5847 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorCombinedSlopeAndShoulderAdaption.cs (.../DesignCalculatorCombinedSlopeAndShoulderAdaption.cs) (revision 5847) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorCombinedSlopeAndShoulderAdaption.cs (.../DesignCalculatorCombinedSlopeAndShoulderAdaption.cs) (revision 5863) @@ -171,7 +171,7 @@ damKernelInput.SubSoilScenario.SoilProfile2D = damKernelInput.OriginalSoilProfile2D.Clone(); Soil embankmentSoil = location.SoilList.GetSoilByName(embankmentDesignParameters.EmbankmentMaterialname); subSoilScenario.SoilProfile2D = - MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(subSoilScenario, surfaceLine, embankmentSoil); + MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(subSoilScenario, surfaceLine, embankmentSoil, location.XSoilGeometry2DOrigin); } DesignCalculatorUtils.KernelCalculate(out kernelDataInput, kernelWrapper, out kernelDataOutput, damKernelInput, Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityOutwards/MacroStabilityOutwardsKernelWrapper.cs =================================================================== diff -u -r5847 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityOutwards/MacroStabilityOutwardsKernelWrapper.cs (.../MacroStabilityOutwardsKernelWrapper.cs) (revision 5847) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityOutwards/MacroStabilityOutwardsKernelWrapper.cs (.../MacroStabilityOutwardsKernelWrapper.cs) (revision 5863) @@ -105,7 +105,7 @@ } MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(damKernelInput.SubSoilScenario, damKernelInput.Location.SurfaceLine, - damKernelInput.CurrentEmbankmentSoil); + damKernelInput.CurrentEmbankmentSoil, damKernelInput.Location.XSoilGeometry2DOrigin); const bool useRiverLevelLow = true; // Determine PL-lines and create waternet Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs =================================================================== diff -u -r5786 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 5786) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 5863) @@ -1111,6 +1111,7 @@ if ((isPoint2SameAsPoint3 && isPoint1SameAsPoint4) || (isPoint2SameAsPoint4 && isPoint1SameAsPoint3)) { + geometryData.Curves.Remove(line1); return true; } Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelperTests.cs =================================================================== diff -u -r5847 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelperTests.cs (.../MacroStabilityCommonHelperTests.cs) (revision 5847) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelperTests.cs (.../MacroStabilityCommonHelperTests.cs) (revision 5863) @@ -41,7 +41,7 @@ { SoilGeometryProbability soilGeometryProbability = FactoryForSoilGeometryProbabilities.CreateSoilGeometryProbabilityWithSoilProfile1D(); SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineWithDikeAndDitch(); - var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); GeometryData geometry = combinedProfile.Geometry; Assert.Multiple(() => @@ -65,7 +65,7 @@ // Create the same surfaceline as is used for creating the SoilProfile2D in the SoilGeometryProbability SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineWithDikeAndDitch(); // Now combine the soilGeometryProbability with the same SurfaceLine2 which should result in the same SoilProfile2D - MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); GeometryData geometry = soilGeometryProbability.SoilProfile2D.Geometry; Assert.Multiple(() => @@ -94,7 +94,7 @@ surfaceLine.Geometry.SyncCalcPoints(); // Now combine the soilGeometryProbability with the same SurfaceLine2 which should result the SoilProfile2D // being cut on the left with 5.0 meters - var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); GeometryData geometry = combinedProfile.Geometry; Assert.Multiple(() => { @@ -122,7 +122,7 @@ surfaceLine.Geometry.SyncCalcPoints(); // Now combine the soilGeometryProbability with the same SurfaceLine2 which should result the SoilProfile2D // being extended to the left with 5.0 meters - var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); GeometryData geometry = combinedProfile.Geometry; Assert.Multiple(() => { @@ -146,7 +146,7 @@ surfaceLine.Geometry.SyncCalcPoints(); // Now combine the soilGeometryProbability with the same SurfaceLine2 which should result the SoilProfile2D // being cut on the right with 5.0 meters - var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); GeometryData geometry = combinedProfile.Geometry; Assert.Multiple(() => @@ -175,7 +175,7 @@ surfaceLine.Geometry.SyncCalcPoints(); // Now combine the soilGeometryProbability with the same SurfaceLine2 which should result the SoilProfile2D // being extended to the right with 5.0 meters - var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); GeometryData geometry = combinedProfile.Geometry; Assert.Multiple(() => @@ -195,7 +195,7 @@ SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineAboveSurfaceLineDikeAndDitch(); // Now combine the soilGeometryProbability with the surfaceLine which should result that a layer is added on // top of the SoilProfile2D - var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); GeometryData geometry = combinedProfile.Geometry; // For debugging purposes // GeometryExporter.ExportToFile(geometry, GeometryExporter.VisualizationFolder + "Geometry.txt"); @@ -219,7 +219,7 @@ SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineBelowSurfaceLineDikeAndDitch(); // Now combine the soilGeometryProbability with the surfaceLine which should result that the top part of the // SoilProfile2D is removed (between top boundary of the SoilProfile2D and the surfaceLine) - var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); GeometryData geometry = combinedProfile.Geometry; Assert.Multiple(() => @@ -240,7 +240,7 @@ SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineCuttingSurfaceLineDikeAndDitch(); // Now combine the soilGeometryProbability with the surfaceLine which should result that the top part of the // SoilProfile2D is removed (between top boundary of the SoilProfile2D and the surfaceLine) - var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + var combinedProfile = MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); GeometryData geometry = combinedProfile.Geometry; Assert.Multiple(() => @@ -261,7 +261,7 @@ SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineDike(-22.0, "PartlyBelowBottom"); // Now combine the soilGeometryProbability with the surfaceLine which should in an exception, because the surfaceLine // is partly below the bottom of the SoilProfile2D - Assert.Throws(() => { MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); }); + Assert.Throws(() => { MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); }); } [Test] @@ -271,14 +271,14 @@ SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineDikeNonStrictAscending(); // Now combine the soilGeometryProbability with the surfaceLine which should in an exception, because the surfaceLine // is not strictly ascending - Assert.Throws(() => { MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); }); + Assert.Throws(() => { MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); }); } private static SoilGeometryProbability CreateSoilGeometryProbabilityWithSoilProfile2DWithSurfaceLineDitchDike() { SoilGeometryProbability soilGeometryProbability = FactoryForSoilGeometryProbabilities.CreateSoilGeometryProbabilityWithSoilProfile1D(); SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineWithDikeAndDitch(); - MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); + MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil(), 0); return soilGeometryProbability; } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/IssuesTests.cs =================================================================== diff -u -r5848 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/IssuesTests.cs (.../IssuesTests.cs) (revision 5848) +++ DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/IssuesTests.cs (.../IssuesTests.cs) (revision 5863) @@ -38,9 +38,9 @@ private const string tutorialStability2D = @"TestFiles\InputTutorialStability2D.xml"; [Test] - [TestCase("DWP_2", 1,15, 97, 83, 46,1.360)] - [TestCase("DWP_8", 7,26, 129, 104, 53, 1.016)] - [TestCase("DWP_16", 15,26, 117, 92, 47, 0.742)] + [TestCase("DWP_2", 1,15, 97, 83, 46,1.393)] + [TestCase("DWP_8", 7,26, 129, 104, 53, 1.051)] + [TestCase("DWP_16", 15,26, 117, 92, 47, 0.749)] [TestCase("DWP_20", 19,23, 113, 91, 50, 1.523)] public void TestGeometryAndResultForIssueWithDwpsFromTutorial(string location, int segmentIndex, int surfaceCount, int curveCount, int pointCount, int surfaceLinePointCount, double safetyFactor) { @@ -61,7 +61,7 @@ Soil soil = engineInterface.DamProjectData.Dike.SoilList.GetSoilByName(soilName); // To be able to check the geometry, create it here. SoilProfile2D soilProfile2D = SoilProfile2DSurfaceLineHelper.CombineSurfaceLineWithSoilProfile2D(surfaceLine.Geometry, - engineInterface.DamProjectData.Segments[segmentIndex].SoilProfileProbabilities[0].SoilProfile2D, soil); + engineInterface.DamProjectData.Segments[segmentIndex].SoilProfileProbabilities[0].SoilProfile2D, soil, 0.0); // For debugging purposes // geometry = soilProfile2D.Geometry; // GeometryExporter.ExportToFile(geometry, GeometryExporter.VisualizationFolder + "Geometry.txt"); @@ -85,28 +85,30 @@ } [Test, Category(Categories.WorkInProgress)] - [TestCase("DWP_1", 0, 1.220)] - [TestCase("DWP_6", 5, 1.580)] - [TestCase("DWP_7", 6, 1.200)] + [TestCase("DWP_1", 0, 1.248)] + [TestCase("DWP_6", 5, 1.000)] + [TestCase("DWP_7", 6, 1.000)] + [TestCase("DWP_20", 19, 1.000)] public void GivenLocationFromDesignTutorialStability_WhenCalculating_ThenResultAvailable(string location, int segmentIndex, double safetyFactor) { string inputString = File.ReadAllText(tutorialStability2D); string[] locations = [location]; inputString = XmlAdapter.SelectLocations(inputString, locations); var engineInterface = new EngineInterface(inputString); + double shift = engineInterface.DamProjectData.Dike.Locations[0].XSoilGeometry2DOrigin; SurfaceLine2 surfaceLine = engineInterface.DamProjectData.Dike.Locations[0].SurfaceLine; string soilName = engineInterface.DamProjectData.Dike.Locations[0].DikeEmbankmentMaterial; Soil fillingMaterial = engineInterface.DamProjectData.Dike.SoilList.GetSoilByName(soilName); SoilProfile2D soilProfile2D = SoilProfile2DSurfaceLineHelper.CombineSurfaceLineWithSoilProfile2D(surfaceLine.Geometry, - engineInterface.DamProjectData.Segments[segmentIndex].SoilProfileProbabilities[0].SoilProfile2D, fillingMaterial); + engineInterface.DamProjectData.Segments[segmentIndex].SoilProfileProbabilities[0].SoilProfile2D, fillingMaterial, shift); if (location == "DWP_1") { Assert.Multiple(() => { Assert.That(soilProfile2D.Geometry.Surfaces, Has.Count.EqualTo(20)); Assert.That(soilProfile2D.Surfaces, Has.Count.EqualTo(20)); - Assert.That(soilProfile2D.Surfaces.Where(s => s.SoilName == fillingMaterial.Name).ToList(), Has.Count.EqualTo(1)); + Assert.That(soilProfile2D.Surfaces.Where(s => s.SoilName == fillingMaterial.Name).ToList(), Has.Count.EqualTo(3)); }); } Index: DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geotechnics/SoilProfile2DSurfaceLineHelperTests.cs =================================================================== diff -u -r5847 -r5863 --- DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geotechnics/SoilProfile2DSurfaceLineHelperTests.cs (.../SoilProfile2DSurfaceLineHelperTests.cs) (revision 5847) +++ DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geotechnics/SoilProfile2DSurfaceLineHelperTests.cs (.../SoilProfile2DSurfaceLineHelperTests.cs) (revision 5863) @@ -22,7 +22,6 @@ using System.Collections.Generic; using System.Linq; using Deltares.DamEngine.Data.Geometry; -using Deltares.DamEngine.Data.GeometryExport; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard; using Deltares.DamEngine.TestHelpers.Factories; @@ -88,6 +87,249 @@ } } + private static IEnumerable ZigZagSurfaceLinesTestCases + { + get + { + var soil1 = new Soil("Soil1"); + var soil2 = new Soil("Soil2"); + var soil3 = new Soil("Soil3"); + var soil4 = new Soil("Soil4"); + var soil5 = new Soil("Soil5"); + var soil6 = new Soil("Soil6"); + var soilFilling = new Soil("Filling material"); + yield return new TestCaseData( + new TestCaseZigZagSurfaceLine + { + TestNumber = 1, + GivenZigZagSurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineInZigZag(-50, 10), + GivenXStartOfSoilProfile = -60, + GivenShift = 10, + ExpectedSurfaceCount = 10, + // 4 extra surfaces created : 2 below the highest corners of the "zigzag" surface line + 2 on the left side (between Z=60 and 70) + ExpectedFilling1 = FactoryForSoilProfiles.CreateQuadrilateralSoilLayer2D(new Point2D(-50, 10), new Point2D(-30, 12), new Point2D(-10, 10), new Point2D(-20, 10), soilFilling), + ExpectedFilling2 = FactoryForSoilProfiles.CreateQuadrilateralSoilLayer2D(new Point2D(30, 10), new Point2D(50, 12), new Point2D(70, 10), new Point2D(60, 10), soilFilling), + ExpectedExtendedSurface1 = null, + ExpectedExtendedSurface3 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(10, 0, 60, 70, soil3), + ExpectedExtendedSurface4 = null, + ExpectedExtendedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 60, 70, soil6), + ExpectedSurface1 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(10, 0, -50, -20, soil1), + ExpectedSurface2 = FactoryForSoilProfiles.CreateHexagonSoilLayer2D(new Point2D(-20, 10), new Point2D(-10, 10), new Point2D(0, 9), new Point2D(0, 0),new Point2D(-10, 0), new Point2D(-20, 0), soil2), + ExpectedSurface3 = FactoryForSoilProfiles.CreateHeptagonSoilLayer2D(new Point2D(0, 9), new Point2D(10, 8), new Point2D(30, 10), new Point2D(60, 10), new Point2D(60, 0), new Point2D(35, 0), new Point2D(0, 0), soil3), + ExpectedSurface4 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-50, 0), new Point2D(-20, 0), new Point2D(-10, 0), new Point2D(-10, -15), new Point2D(-50, -15), soil4), + ExpectedSurface5 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-10, 0), new Point2D(0, 0), new Point2D(35, 0), new Point2D(35, -15), new Point2D(-10, -15), soil5), + ExpectedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 35, 60, soil6) + + }).SetName("Test 1: Surface line intersects the surface line of the shifted soil profile and starts at the " + + "same point (X=-50)"); + + yield return new TestCaseData( + new TestCaseZigZagSurfaceLine() + { + TestNumber = 2, + GivenZigZagSurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineInZigZag(-50, 13), + GivenXStartOfSoilProfile = -60, + GivenShift = 10, + ExpectedSurfaceCount = 9, + // 3 extra surfaces created: 1 below the "zigzag" surface line + 2 on the left side (between Z=60 and 70) + ExpectedFilling1 = FactoryForSoilProfiles.CreatePolygoneSoilLayer2D([ + ..new[] + { + new Point2D(-50, 13), + new Point2D(-30, 15), + new Point2D(10, 11), + new Point2D(50, 15), + new Point2D(70, 13), + new Point2D(70, 10), + new Point2D(60, 10), + new Point2D(0, 10), + new Point2D(-20, 10), + new Point2D(-50, 10) + } + ], soilFilling), + ExpectedFilling2 = null, + ExpectedExtendedSurface1 = null, + ExpectedExtendedSurface3 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(10, 0, 60, 70, soil3), + ExpectedExtendedSurface4 = null, + ExpectedExtendedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 60, 70, soil6), + ExpectedSurface1 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(10, 0, -50, -20, soil1), + ExpectedSurface2 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-20, 10), new Point2D(0, 10), new Point2D(0, 0), new Point2D(-10, 0), new Point2D(-20, 0), soil2), + ExpectedSurface3 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(0, 10), new Point2D(60, 10), new Point2D(60, 0), new Point2D(35, 0), new Point2D(0, 0), soil3), + ExpectedSurface4 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-50, 0), new Point2D(-20, 0), new Point2D(-10, 0), new Point2D(-10, -15), new Point2D(-50, -15), soil4), + ExpectedSurface5 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-10, 0), new Point2D(0, 0), new Point2D(35, 0), new Point2D(35, -15), new Point2D(-10, -15), soil5), + ExpectedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 35, 60, soil6) + }).SetName("Test 2: Surface line is completely above the surface line of shifted soil profile (shift = 10) " + + "and starts at the same point (X=-50)"); + + yield return new TestCaseData( + new TestCaseZigZagSurfaceLine + { + TestNumber = 3, + GivenZigZagSurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineInZigZag(-50, 5), + GivenXStartOfSoilProfile = -60, + GivenShift = 10, + ExpectedSurfaceCount = 8, + // 2 extra surfaces created on the left side (between Z=60 and 70) + ExpectedFilling1 = null, + ExpectedFilling2 = null, + ExpectedExtendedSurface1 = null, + ExpectedExtendedSurface3 = FactoryForSoilProfiles.CreateQuadrilateralSoilLayer2D(new Point2D(60, 6), new Point2D(70, 5), new Point2D(70, 0), new Point2D(60, 0), soil3), + ExpectedExtendedSurface4= null, + ExpectedExtendedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 60, 70, soil6), + ExpectedSurface1 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-50, 5), new Point2D(-30, 7), new Point2D(-20, 6), new Point2D(-20, 0), new Point2D(-50, 0),soil1), + ExpectedSurface2 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-20, 6), new Point2D(0, 4), new Point2D(0, 0), new Point2D(-10, 0),new Point2D(-20, 0), soil2), + ExpectedSurface3 = FactoryForSoilProfiles.CreateHeptagonSoilLayer2D(new Point2D(0, 4), new Point2D(10, 3), new Point2D(50, 7), new Point2D(60, 6), new Point2D(60, 0), new Point2D(35, 0), new Point2D(0, 0), soil3), + ExpectedSurface4 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-50, 0), new Point2D(-20, 0), new Point2D(-10, 0), new Point2D(-10, -15), new Point2D(-50, -15), soil4), + ExpectedSurface5 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-10, 0), new Point2D(0, 0), new Point2D(35, 0), new Point2D(35, -15), new Point2D(-10, -15), soil5), + ExpectedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 35, 60, soil6) + }).SetName("Test 3: Surface line is completely in the top layer of the shifted soil profile (shift = 10) and " + + "starts at the same point (X=-50)"); + + yield return new TestCaseData( + new TestCaseZigZagSurfaceLine + { + TestNumber = 4, + GivenZigZagSurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineInZigZag(-50, 0), + GivenXStartOfSoilProfile = -60, + GivenShift = 10, + ExpectedSurfaceCount = 8, + // 2 extra surfaces created on the left side (between Z=60 and 70) + ExpectedFilling1 = null, + ExpectedFilling2 = null, + ExpectedExtendedSurface1 = null, + ExpectedExtendedSurface3 = FactoryForSoilProfiles.CreateTriangularSoilLayer2D(new Point2D(60, 1), new Point2D(70, 0), new Point2D(60, 0), soil3), + ExpectedExtendedSurface4 = null, + ExpectedExtendedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 60, 70, soil6), + ExpectedSurface1 = FactoryForSoilProfiles.CreateQuadrilateralSoilLayer2D(new Point2D(-50, 0), new Point2D(-30, 2), new Point2D(-20, 1), new Point2D(-20, 0), soil1), + ExpectedSurface2 = FactoryForSoilProfiles.CreateTriangularSoilLayer2D(new Point2D(-20, 1), new Point2D(-10, 0), new Point2D(-20, 0), soil2), + ExpectedSurface3 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(30, 0), new Point2D(50, 2), new Point2D(60, 1), new Point2D(60, 0), new Point2D(35, 0), soil3), + ExpectedSurface4 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-50, 0), new Point2D(-20, 0), new Point2D(-10, 0), new Point2D(-10, -15), new Point2D(-50, -15), soil4), + ExpectedSurface5 = FactoryForSoilProfiles.CreateHexagonSoilLayer2D(new Point2D(-10, 0), new Point2D(10, -2), new Point2D(30, 0), new Point2D(35, 0), new Point2D(35, -15), new Point2D(-10, -15), soil5), + ExpectedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 35, 60, soil6) + }).SetName("Test 4: Surface line intersects the layer separation of shifted soil profile (shift = 10) " + + "and starts at the same point (X=-50)"); + + yield return new TestCaseData( + new TestCaseZigZagSurfaceLine + { + TestNumber = 5, + GivenZigZagSurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineInZigZag(-40, 10), + GivenXStartOfSoilProfile = -65, + GivenShift = 15, + ExpectedSurfaceCount = 10, + // Only few surfaces are tested + ExpectedFilling1 = FactoryForSoilProfiles.CreateQuadrilateralSoilLayer2D(new Point2D(-40, 10), new Point2D(-20, 12), new Point2D(0, 10), new Point2D(-20, 10), soilFilling), + ExpectedFilling2 = FactoryForSoilProfiles.CreateQuadrilateralSoilLayer2D(new Point2D(40, 10), new Point2D(60, 12), new Point2D(80, 10), new Point2D(60, 10), soilFilling), + ExpectedExtendedSurface1 = null, + ExpectedExtendedSurface3 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(10, 0, 60, 80, soil3), + ExpectedExtendedSurface4 = null, + ExpectedExtendedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 60, 80, soil6), + ExpectedSurface1 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(10, 0, -40, -20, soil1), + ExpectedSurface2 = null, // not null but not tested + ExpectedSurface3 = null, // not null but not tested + ExpectedSurface4 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-40, 0), new Point2D(-20, 0), new Point2D(-10, 0), new Point2D(-10, -15), new Point2D(-40, -15), soil4), + ExpectedSurface5 = null, // not null but not tested + ExpectedSurface6 = null // not null but not tested + }).SetName("Test 5: Surface line intersects the surface line of shifted soil profile (shift = 15) and" + + "starts at X=-40 (i.e. 10 m right)"); + + yield return new TestCaseData( + new TestCaseZigZagSurfaceLine + { + TestNumber = 6, + GivenZigZagSurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineInZigZag(10, 10), + GivenXStartOfSoilProfile = -30, + GivenShift = -20, + ExpectedSurfaceCount = 7, + // Only few surfaces are tested + ExpectedFilling1 = FactoryForSoilProfiles.CreateTriangularSoilLayer2D(new Point2D(10, 10), new Point2D(30, 12), new Point2D(50, 10), soilFilling), + ExpectedFilling2 = FactoryForSoilProfiles.CreateTriangularSoilLayer2D(new Point2D(90, 10), new Point2D(110, 12), new Point2D(130, 10), soilFilling), + ExpectedExtendedSurface1 = null, + ExpectedExtendedSurface3 = FactoryForSoilProfiles.CreateHexagonSoilLayer2D(new Point2D(60, 9), new Point2D(70, 8), new Point2D(90, 10), new Point2D(130, 10), new Point2D(130, 0), new Point2D(60, 0), soil3), + ExpectedExtendedSurface4 = null, + ExpectedExtendedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 60, 130, soil6), + ExpectedSurface1 = null, + ExpectedSurface2 = null, + ExpectedSurface3 = FactoryForSoilProfiles.CreateHexagonSoilLayer2D(new Point2D(10, 10), new Point2D(50, 10), new Point2D(60, 9), new Point2D(60, 0), new Point2D(35, 0), new Point2D(10, 0), soil3), + ExpectedSurface4 = null, + ExpectedSurface5 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 10, 35, soil5), + ExpectedSurface6 = null // not null but not tested + }).SetName("Test 6: Surface line intersects the surface line of shifted soil profile (shift = -20) and" + + "starts at X=10 (i.e. 60 m right)"); + + yield return new TestCaseData( + new TestCaseZigZagSurfaceLine + { + TestNumber = 7, + GivenZigZagSurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineInZigZag(-60, 10), + GivenXStartOfSoilProfile = -80, + GivenShift = 30, + ExpectedSurfaceCount = 10, + // Only few surfaces are tested + ExpectedFilling1 = FactoryForSoilProfiles.CreateQuadrilateralSoilLayer2D(new Point2D(-60, 10), new Point2D(-40, 12), new Point2D(-20, 10), new Point2D(-50, 10), soilFilling), + ExpectedFilling2 = FactoryForSoilProfiles.CreateTriangularSoilLayer2D(new Point2D(20, 10), new Point2D(40, 12), new Point2D(60, 10), soilFilling), + ExpectedExtendedSurface1 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(10, 0, -60, -50, soil1), + ExpectedExtendedSurface3 = null, + ExpectedExtendedSurface4 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, -60, -50, soil4), + ExpectedExtendedSurface6 = null, + ExpectedSurface1 = null, // not null but not tested + ExpectedSurface2 = null, // not null but not tested + ExpectedSurface3 = null, // not null but not tested + ExpectedSurface4 = null, // not null but not tested + ExpectedSurface5 = null, // not null but not tested + ExpectedSurface6 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, 35, 60, soil6) + }).SetName("Test 7: Surface line intersects the surface line of shifted soil profile (shift = 30) and" + + "starts at X=-60 (i.e. 10 m left)"); + + yield return new TestCaseData( + new TestCaseZigZagSurfaceLine + { + TestNumber = 8, + GivenZigZagSurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineInZigZag(-110, 10), + GivenXStartOfSoilProfile = -25, + GivenShift = -25, + ExpectedSurfaceCount = 9, + // Only few surfaces are tested + ExpectedFilling1 = FactoryForSoilProfiles.CreateTriangularSoilLayer2D(new Point2D(-110, 10), new Point2D(-90, 12), new Point2D(-70, 10), soilFilling), + ExpectedFilling2 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-30, 10), new Point2D(-10, 12), new Point2D(10, 10), new Point2D(0, 10), new Point2D(-20, 10), soilFilling), + ExpectedExtendedSurface1 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-110, 10), new Point2D(-70, 10), new Point2D(-50, 8), new Point2D(-50, 0), new Point2D(-110, 0), soil1), + ExpectedExtendedSurface3 = null, + ExpectedExtendedSurface4 = FactoryForSoilProfiles.CreateRectangularSoilLayer2D(0, -15, -110, -50, soil4), + ExpectedExtendedSurface6 = null, + ExpectedSurface1 = null, // not null but not tested + ExpectedSurface2 = null, // not null but not tested + ExpectedSurface3 = null, // not null but not tested + ExpectedSurface4 = null, //not null but not tested + ExpectedSurface5 = FactoryForSoilProfiles.CreatePentagonSoilLayer2D(new Point2D(-10, 0), new Point2D(0, 0), new Point2D(10, 0), new Point2D(10, -15), new Point2D(-10, -15), soil5), + ExpectedSurface6 = null + }).SetName("Test 8: Surface line intersects the surface line of shifted soil profile (shift = -25) and" + + "starts at X=-110 (i.e. 60 m left)"); + + yield return new TestCaseData( + new TestCaseZigZagSurfaceLine + { + TestNumber = 9, + GivenZigZagSurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineInZigZag(50, -5), + GivenXStartOfSoilProfile = -50, + GivenShift = 0, + ExpectedSurfaceCount = 2, + ExpectedFilling1 = null, + ExpectedFilling2 = null, + ExpectedExtendedSurface1 = null, + ExpectedExtendedSurface3 = null, + ExpectedExtendedSurface4 = null, + ExpectedExtendedSurface6 = FactoryForSoilProfiles.CreateHeptagonSoilLayer2D(new Point2D(60, -4), new Point2D(70, -3), new Point2D(110, -7), new Point2D(150, -3), new Point2D(170, -5), new Point2D(170, -15), new Point2D(60, -15),soil6), + ExpectedSurface1 = null, + ExpectedSurface2 = null, + ExpectedSurface3 = null, + ExpectedSurface4 = null, + ExpectedSurface5 = null, + ExpectedSurface6 = FactoryForSoilProfiles.CreateQuadrilateralSoilLayer2D(new Point2D(50, -5), new Point2D(60, -4), new Point2D(60, -15), new Point2D(50, -15), soil6) + }).SetName("Test 9: Surface line starts inside surface 6 (right bottom) of the soil profile"); + + } + } + [Test] [TestCase(PositionToSoilProfile2D.LeftOfSoilProfile, false)] [TestCase(PositionToSoilProfile2D.RightOfSoilProfile, false)] @@ -113,12 +355,74 @@ Name = "dikemat" }; SoilProfile2D newSoilProfile2D = SoilProfile2DSurfaceLineHelper.CombineSurfaceLineWithSoilProfile2D( - testCaseSurfaceLine.SurfaceLine.Geometry, soilProfile2D, defaultSoil); - + testCaseSurfaceLine.SurfaceLine.Geometry, soilProfile2D, defaultSoil, 0); Assert.That(newSoilProfile2D, Is.Not.Null); Assert.That(newSoilProfile2D.Surfaces, Has.Count.EqualTo(testCaseSurfaceLine.SurfaceCount)); } + [Test, TestCaseSource(nameof(ZigZagSurfaceLinesTestCases))] + public void GivenComplexShiftedSoilProfile2D_WhenCombiningWithZigZagSurfaceLine_ThenCorrectNewSoilProfile2DIsCreated(TestCaseZigZagSurfaceLine testCaseSurfaceLine) + { + // Given + SoilProfile2D soilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DWithSixSurfacesFormingTwoLayers(testCaseSurfaceLine.GivenXStartOfSoilProfile); + var defaultSoil = new Soil + { + Name = "Filling material" + }; + // When + SoilProfile2D newSoilProfile2D = SoilProfile2DSurfaceLineHelper.CombineSurfaceLineWithSoilProfile2D( + testCaseSurfaceLine.GivenZigZagSurfaceLine.Geometry, soilProfile2D, defaultSoil, testCaseSurfaceLine.GivenShift); + + // Then + if (testCaseSurfaceLine.ExpectedSurfaceCount == 0) + { + Assert.That(newSoilProfile2D, Is.Null); + } + else + { + Assert.That(newSoilProfile2D, Is.Not.Null); + Assert.That(newSoilProfile2D.Surfaces, Has.Count.EqualTo(testCaseSurfaceLine.ExpectedSurfaceCount)); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedFilling1); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedFilling2); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedExtendedSurface1); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedExtendedSurface3); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedExtendedSurface4); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedExtendedSurface6); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedSurface1); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedSurface2); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedSurface3); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedSurface4); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedSurface5); + CheckSoilProfileContainsSoilLayer(newSoilProfile2D, testCaseSurfaceLine.ExpectedSurface6); + } + + // New surface line is checked only for test case 6 + if (testCaseSurfaceLine.TestNumber == 6) + { + Assert.That(newSoilProfile2D, Is.Not.Null); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points, Has.Count.EqualTo(8)); + Assert.Multiple(() => + { + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[0].X, Is.EqualTo(10)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[0].Z, Is.EqualTo(10)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[1].X, Is.EqualTo(30)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[1].Z, Is.EqualTo(12)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[2].X, Is.EqualTo(50)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[2].Z, Is.EqualTo(10)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[3].X, Is.EqualTo(60)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[3].Z, Is.EqualTo(9)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[4].X, Is.EqualTo(70)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[4].Z, Is.EqualTo(8)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[5].X, Is.EqualTo(90)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[5].Z, Is.EqualTo(10)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[6].X, Is.EqualTo(110)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[6].Z, Is.EqualTo(12)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[7].X, Is.EqualTo(130)); + Assert.That(newSoilProfile2D.Geometry.SurfaceLine.Points[7].Z, Is.EqualTo(10)); + }); + } + } + [Test] [TestCase(0, true)] // Surface line is above the bottom of the soil profile [TestCase(-10, true)] // Surface line is on and above the bottom of the soil profile @@ -148,6 +452,7 @@ { public SurfaceLine2 GivenZigZagSurfaceLine { get; init; } public double GivenXStartOfSoilProfile { get; init; } + public double GivenShift { get; init; } public int ExpectedSurfaceCount { get; init; } public SoilLayer2D ExpectedSurface1 { get; init; } public SoilLayer2D ExpectedSurface2 { get; init; } @@ -298,7 +603,7 @@ // When SoilProfile2D newSoilProfile2D = SoilProfile2DSurfaceLineHelper.CombineSurfaceLineWithSoilProfile2D( - surfaceLine.Geometry, soilProfile2D, defaultSoil); + surfaceLine.Geometry, soilProfile2D, defaultSoil, 0); //Then Assert.That(newSoilProfile2D, Is.Not.Null);