From 2bc3039759def2c6c7abac592f8154ed266b3230 Mon Sep 17 00:00:00 2001 From: Luca Carniato Date: Tue, 19 Nov 2024 17:40:34 +0100 Subject: [PATCH] GRIDEDIT-1526: Refactor ProjectionsOptions, correct orthogonalization projection --- .../include/MeshKernel/LandBoundaries.hpp | 15 ++++++------ .../OrthogonalizationAndSmoothing.hpp | 16 ++++++------- libs/MeshKernel/src/FlipEdges.cpp | 2 +- libs/MeshKernel/src/LandBoundaries.cpp | 14 ++++++----- .../src/OrthogonalizationAndSmoothing.cpp | 12 ++++++---- .../tests/src/LandBoundaryTests.cpp | 8 +++---- .../tests/src/OrthogonalizationTests.cpp | 24 +++++++++---------- libs/MeshKernelApi/src/MeshKernel.cpp | 6 ++--- 8 files changed, 51 insertions(+), 46 deletions(-) diff --git a/libs/MeshKernel/include/MeshKernel/LandBoundaries.hpp b/libs/MeshKernel/include/MeshKernel/LandBoundaries.hpp index 8e90b4eeb..19818a076 100644 --- a/libs/MeshKernel/include/MeshKernel/LandBoundaries.hpp +++ b/libs/MeshKernel/include/MeshKernel/LandBoundaries.hpp @@ -50,14 +50,13 @@ namespace meshkernel { public: - /// Enumerator describing the options how to project to the land boundary - enum class ProjectToLandBoundaryOption + /// Enumerator describing the options how to project + enum class ProjectionsOptions { - DoNotProjectToLandBoundary = 0, - ToOriginalNetBoundary = 1, - OuterMeshBoundaryToLandBoundary = 2, - InnerAndOuterMeshBoundaryToLandBoundary = 3, - WholeMesh = 4 + DoNotProject = 0, + ToOriginalMeshBoundary = 1, + OuterMeshBoundaryToLandBoundaries = 2, + InnerAndOuterMeshBoundaryToLandboundaries = 3 }; /// @brief Default constructor @@ -81,7 +80,7 @@ namespace meshkernel /// @brief Find the mesh boundary line closest to the land boundary (find_nearest_meshline). /// @param[in] projectToLandBoundaryOption The option describing the projection to the land boundary. - void FindNearestMeshBoundary(ProjectToLandBoundaryOption projectToLandBoundaryOption); + void FindNearestMeshBoundary(ProjectionsOptions projectToLandBoundaryOption); /// @brief Snap the mesh nodes to land boundaries (snap_to_landboundary) [[nodiscard]] std::unique_ptr SnapMeshToLandBoundaries() const; diff --git a/libs/MeshKernel/include/MeshKernel/OrthogonalizationAndSmoothing.hpp b/libs/MeshKernel/include/MeshKernel/OrthogonalizationAndSmoothing.hpp index f6deee473..72c2b3dd0 100644 --- a/libs/MeshKernel/include/MeshKernel/OrthogonalizationAndSmoothing.hpp +++ b/libs/MeshKernel/include/MeshKernel/OrthogonalizationAndSmoothing.hpp @@ -95,7 +95,7 @@ namespace meshkernel std::unique_ptr orthogonalizer, std::unique_ptr polygon, std::unique_ptr landBoundaries, - LandBoundaries::ProjectToLandBoundaryOption projectToLandBoundaryOption, + LandBoundaries::ProjectionsOptions projectToLandBoundaryOption, const OrthogonalizationParameters& orthogonalizationParameters); /// @brief Initializes the object @@ -140,13 +140,13 @@ namespace meshkernel /// @brief Compute nodes local coordinates (comp_local_coords) void ComputeCoordinates() const; - Mesh2D& m_mesh; ///< A reference to mesh - std::unique_ptr m_smoother; ///< A pointer to the smoother - std::unique_ptr m_orthogonalizer; ///< A pointer to the orthogonalizer - std::unique_ptr m_polygons; ///< The polygon pointer where to perform the orthogonalization - std::unique_ptr m_landBoundaries; ///< The land boundaries pointer - LandBoundaries::ProjectToLandBoundaryOption m_projectToLandBoundaryOption; ///< The project to land boundary option - OrthogonalizationParameters m_orthogonalizationParameters; ///< The orthogonalization parameters + Mesh2D& m_mesh; ///< A reference to mesh + std::unique_ptr m_smoother; ///< A pointer to the smoother + std::unique_ptr m_orthogonalizer; ///< A pointer to the orthogonalizer + std::unique_ptr m_polygons; ///< The polygon pointer where to perform the orthogonalization + std::unique_ptr m_landBoundaries; ///< The land boundaries pointer + LandBoundaries::ProjectionsOptions m_projectOptions; ///< The projection options + OrthogonalizationParameters m_orthogonalizationParameters; ///< The orthogonalization parameters std::vector m_localCoordinatesIndices; ///< Used in sphericalAccurate projection (iloc) std::vector m_localCoordinates; ///< Used in sphericalAccurate projection (xloc,yloc) diff --git a/libs/MeshKernel/src/FlipEdges.cpp b/libs/MeshKernel/src/FlipEdges.cpp index 7657b382d..99c8f9d22 100644 --- a/libs/MeshKernel/src/FlipEdges.cpp +++ b/libs/MeshKernel/src/FlipEdges.cpp @@ -47,7 +47,7 @@ FlipEdges::FlipEdges(Mesh2D& mesh, { if (m_projectToLandBoundary) { - m_landBoundaries.FindNearestMeshBoundary(LandBoundaries::ProjectToLandBoundaryOption::WholeMesh); + m_landBoundaries.FindNearestMeshBoundary(LandBoundaries::ProjectionsOptions::OuterMeshBoundaryToLandBoundaries); } } diff --git a/libs/MeshKernel/src/LandBoundaries.cpp b/libs/MeshKernel/src/LandBoundaries.cpp index 6ced51f4d..2ec4146c1 100644 --- a/libs/MeshKernel/src/LandBoundaries.cpp +++ b/libs/MeshKernel/src/LandBoundaries.cpp @@ -98,18 +98,20 @@ void LandBoundaries::Administrate() } } -void LandBoundaries::FindNearestMeshBoundary(ProjectToLandBoundaryOption projectToLandBoundaryOption) +void LandBoundaries::FindNearestMeshBoundary(ProjectionsOptions projectToLandBoundaryOption) { - if (m_landBoundary.IsEmpty() || projectToLandBoundaryOption == ProjectToLandBoundaryOption::DoNotProjectToLandBoundary) + if (m_landBoundary.IsEmpty()) { return; } - if (projectToLandBoundaryOption == ProjectToLandBoundaryOption::OuterMeshBoundaryToLandBoundary || - projectToLandBoundaryOption == ProjectToLandBoundaryOption::InnerAndOuterMeshBoundaryToLandBoundary) + if (projectToLandBoundaryOption != ProjectionsOptions::OuterMeshBoundaryToLandBoundaries && + projectToLandBoundaryOption != ProjectionsOptions::InnerAndOuterMeshBoundaryToLandboundaries) { - m_findOnlyOuterMeshBoundary = true; + return; } + m_findOnlyOuterMeshBoundary = true; + Administrate(); @@ -124,7 +126,7 @@ void LandBoundaries::FindNearestMeshBoundary(ProjectToLandBoundaryOption project { const auto [_, numRejectedPaths] = MakePath(landBoundarySegment); - if (numRejectedPaths > 0 && projectToLandBoundaryOption == ProjectToLandBoundaryOption::InnerAndOuterMeshBoundaryToLandBoundary) + if (numRejectedPaths > 0 && projectToLandBoundaryOption == ProjectionsOptions::InnerAndOuterMeshBoundaryToLandboundaries) { m_findOnlyOuterMeshBoundary = false; MakePath(landBoundarySegment); diff --git a/libs/MeshKernel/src/OrthogonalizationAndSmoothing.cpp b/libs/MeshKernel/src/OrthogonalizationAndSmoothing.cpp index 0067c3804..bcd0ad1f2 100644 --- a/libs/MeshKernel/src/OrthogonalizationAndSmoothing.cpp +++ b/libs/MeshKernel/src/OrthogonalizationAndSmoothing.cpp @@ -44,14 +44,14 @@ OrthogonalizationAndSmoothing::OrthogonalizationAndSmoothing(Mesh2D& mesh, std::unique_ptr orthogonalizer, std::unique_ptr polygon, std::unique_ptr landBoundaries, - LandBoundaries::ProjectToLandBoundaryOption projectToLandBoundaryOption, + LandBoundaries::ProjectionsOptions projectToLandBoundaryOption, const OrthogonalizationParameters& orthogonalizationParameters) : m_mesh(mesh), m_smoother(std::move(smoother)), m_orthogonalizer(std::move(orthogonalizer)), m_polygons(std::move(polygon)), m_landBoundaries(std::move(landBoundaries)), - m_projectToLandBoundaryOption(projectToLandBoundaryOption) + m_projectOptions(projectToLandBoundaryOption) { CheckOrthogonalizationParameters(orthogonalizationParameters); m_orthogonalizationParameters = orthogonalizationParameters; @@ -91,8 +91,12 @@ std::unique_ptr OrthogonalizationAndSmoothing::Initializ m_originalNodes = m_mesh.Nodes(); m_orthogonalCoordinates = m_mesh.Nodes(); - // account for enclosing polygon - m_landBoundaries->FindNearestMeshBoundary(m_projectToLandBoundaryOption); + // + if (m_projectOptions == LandBoundaries::ProjectionsOptions::OuterMeshBoundaryToLandBoundaries || + m_projectOptions == LandBoundaries::ProjectionsOptions::InnerAndOuterMeshBoundaryToLandboundaries) + { + m_landBoundaries->FindNearestMeshBoundary(m_projectOptions); + } // for spherical accurate computations we need to call PrapareOuterIteration (orthonet_comp_ops) if (m_mesh.m_projection == Projection::sphericalAccurate) diff --git a/libs/MeshKernel/tests/src/LandBoundaryTests.cpp b/libs/MeshKernel/tests/src/LandBoundaryTests.cpp index 74298cc0c..d064397a8 100644 --- a/libs/MeshKernel/tests/src/LandBoundaryTests.cpp +++ b/libs/MeshKernel/tests/src/LandBoundaryTests.cpp @@ -25,7 +25,7 @@ TEST(LandBoundaries, OneLandBoundary) // Execute auto landboundaries = meshkernel::LandBoundaries(landBoundaryPolygon, *mesh, polygons); - landboundaries.FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectToLandBoundaryOption ::OuterMeshBoundaryToLandBoundary); + landboundaries.FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectionsOptions ::OuterMeshBoundaryToLandBoundaries); // Checks EXPECT_EQ(1, landboundaries.m_meshNodesLandBoundarySegments[0]); @@ -62,7 +62,7 @@ TEST(LandBoundaries, TwoLandBoundaries) // Execute auto landboundaries = std::make_shared(landBoundaryPolygon, *mesh, polygons); - landboundaries->FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectToLandBoundaryOption::OuterMeshBoundaryToLandBoundary); + landboundaries->FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectionsOptions::OuterMeshBoundaryToLandBoundaries); // Checks EXPECT_EQ(2, landboundaries->m_meshNodesLandBoundarySegments[0]); @@ -94,7 +94,7 @@ TEST(LandBoundaries, OneCrossingLandBoundary) // Execute auto landboundaries = std::make_shared(landBoundaryPolygon, *mesh, polygons); - landboundaries->FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectToLandBoundaryOption ::OuterMeshBoundaryToLandBoundary); + landboundaries->FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectionsOptions ::OuterMeshBoundaryToLandBoundaries); // Checks EXPECT_EQ(0, landboundaries->m_meshNodesLandBoundarySegments[0]); @@ -130,7 +130,7 @@ TEST(LandBoundaries, TwoCrossingLandBoundary) // Execute auto landboundaries = std::make_shared(landBoundaryPolygon, *mesh, polygons); - landboundaries->FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectToLandBoundaryOption ::OuterMeshBoundaryToLandBoundary); + landboundaries->FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectionsOptions ::OuterMeshBoundaryToLandBoundaries); // Checks EXPECT_EQ(2, landboundaries->m_meshNodesLandBoundarySegments[0]); diff --git a/libs/MeshKernel/tests/src/OrthogonalizationTests.cpp b/libs/MeshKernel/tests/src/OrthogonalizationTests.cpp index bec025a04..755114d00 100644 --- a/libs/MeshKernel/tests/src/OrthogonalizationTests.cpp +++ b/libs/MeshKernel/tests/src/OrthogonalizationTests.cpp @@ -33,7 +33,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationOneQuadOneTriangle) {3, 2}, {3, 1}}; - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.inner_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -82,7 +82,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationSmallTriangularGrid) // now build node-edge mapping auto mesh = ReadLegacyMesh2DFromFile(TEST_FOLDER + "/data/SmallTriangularGrid_net.nc"); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.outer_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -140,7 +140,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationSmallTriangularGridAsNcFile // now build node-edge mapping auto mesh = MakeSmallSizeTriangularMeshForTestingAsNcFile(); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.outer_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -200,7 +200,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationMediumTriangularGridWithPol // The original mesh nodes const std::vector meshNodes(mesh->Nodes()); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.outer_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -278,7 +278,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationMediumTriangularGridWithUnd // now build node-edge mapping auto mesh = ReadLegacyMesh2DFromFile(TEST_FOLDER + "/data/TestOrthogonalizationMediumTriangularGrid_net.nc"); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.outer_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -346,7 +346,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationFourQuads) { auto mesh = MakeRectangularMeshForTesting(3, 3, 1.0, Projection::cartesian); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.inner_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -393,7 +393,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizeAndSnapToLandBoundaries) {missing::doubleValue, missing::doubleValue}}; // snap to land boundaries - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::OuterMeshBoundaryToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::OuterMeshBoundaryToLandBoundaries; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.outer_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -449,7 +449,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationSphericalRectangular) // 1 Setup auto mesh = MakeRectangularMeshForTesting(4, 4, 0.003, Projection::spherical, {41.1, 41.1}); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.outer_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -537,7 +537,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationSmallTriangulargridSpherica auto mesh = std::make_shared(edges, nodes, Projection::spherical); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.outer_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -598,7 +598,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationSmallTriangulargridSpherica auto mesh = std::make_shared(edges, nodes, Projection::spherical); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.outer_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -692,7 +692,7 @@ TEST(OrthogonalizationAndSmoothing, RefineUndoThenOrthogonalise) auto refinementUndoAction = meshRefinement.Compute(); refinementUndoAction->Restore(); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.inner_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; @@ -778,7 +778,7 @@ TEST(OrthogonalizationAndSmoothing, OrthogonalizationWithGapsInNodeAndEdgeLists) FlipEdges flipEdges1(mesh, *boundary, true, false); - const auto projectToLandBoundaryOption = LandBoundaries::ProjectToLandBoundaryOption::DoNotProjectToLandBoundary; + const auto projectToLandBoundaryOption = LandBoundaries::ProjectionsOptions::DoNotProject; OrthogonalizationParameters orthogonalizationParameters; orthogonalizationParameters.outer_iterations = 2; orthogonalizationParameters.boundary_iterations = 25; diff --git a/libs/MeshKernelApi/src/MeshKernel.cpp b/libs/MeshKernelApi/src/MeshKernel.cpp index 521a5552d..f3aaa88f7 100644 --- a/libs/MeshKernelApi/src/MeshKernel.cpp +++ b/libs/MeshKernelApi/src/MeshKernel.cpp @@ -505,7 +505,7 @@ namespace meshkernelapi // Construct all dependencies const auto polygon = meshkernel::Polygons(polygonNodes, meshKernelState[meshKernelId].m_projection); auto landBoundary = meshkernel::LandBoundaries(landBoundariesPoints, *meshKernelState[meshKernelId].m_mesh2d, polygon); - landBoundary.FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectToLandBoundaryOption::InnerAndOuterMeshBoundaryToLandBoundary); + landBoundary.FindNearestMeshBoundary(meshkernel::LandBoundaries::ProjectionsOptions::InnerAndOuterMeshBoundaryToLandboundaries); // Execute algorithm meshKernelUndoStack.Add(landBoundary.SnapMeshToLandBoundaries()); @@ -1274,7 +1274,7 @@ namespace meshkernelapi std::move(orthogonalizer), std::move(polygon), std::move(landBoundary), - static_cast(projectToLandBoundaryOption), + static_cast(projectToLandBoundaryOption), orthogonalizationParameters); meshKernelUndoStack.Add(ortogonalization.Initialize(), meshKernelId); ortogonalization.Compute(); @@ -1322,7 +1322,7 @@ namespace meshkernelapi std::move(orthogonalizer), std::move(polygon), std::move(landBoundary), - static_cast(projectToLandBoundaryOption), + static_cast(projectToLandBoundaryOption), orthogonalizationParameters); meshKernelUndoStack.Add(meshKernelState[meshKernelId].m_meshOrthogonalization->Initialize(), meshKernelId); }