Skip to content

Commit

Permalink
Add mkernel_mesh2d_get_property api (#368 | GRIDEDIT-1407)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucacarniato authored Sep 4, 2024
1 parent f44d353 commit 90bcb59
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 2 deletions.
5 changes: 3 additions & 2 deletions libs/MeshKernel/include/MeshKernel/Mesh2D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ namespace meshkernel
other
};

/// Enumerator for different filtering properties on a 2D mesh
/// Enumerator for different properties on a 2D mesh
enum class Property
{
Orthogonality = 0
Orthogonality = 0,
EdgeLength = 1
};

/// @brief Default destructor
Expand Down
16 changes: 16 additions & 0 deletions libs/MeshKernelApi/include/MeshKernelApi/MeshKernel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,22 @@ namespace meshkernelapi
/// @returns Error code
MKERNEL_API int mkernel_mesh2d_get_orthogonality(int meshKernelId, GeometryList& geometryList);

/// @brief Retrieves a specified property of a 2D mesh.
///
/// @param[in] meshKernelId The id of the mesh state
/// @param[in] propertyValue The value representing the specific property
/// @param[in] geometrylist A reference to a GeometryList object that will be populated with the values of the requested property
/// @returns Error code
MKERNEL_API int mkernel_mesh2d_get_property(int meshKernelId, int propertyValue, const GeometryList& geometrylist);

/// @brief The dimension of a specified property of a 2D mesh.
///
/// @param[in] meshKernelId The id of the mesh state
/// @param[in] propertyValue The value representing the specific property
/// @param[in] dimension The dimension of the specified property
/// @returns Error code
MKERNEL_API int mkernel_mesh2d_get_property_dimension(int meshKernelId, int propertyValue, int& dimension);

/// @brief Gets the small mesh2d flow edges. The flow edges are the edges connecting faces circumcenters.
/// @param[in] meshKernelId The id of the mesh state
/// @param[in] smallFlowEdgesThreshold The configurable threshold for detecting a small flow edge
Expand Down
92 changes: 92 additions & 0 deletions libs/MeshKernelApi/src/MeshKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,98 @@ namespace meshkernelapi
return lastExitCode;
}

MKERNEL_API int mkernel_mesh2d_get_property(int meshKernelId, int propertyValue, const GeometryList& geometryList)
{
lastExitCode = meshkernel::ExitCode::Success;
try
{
if (!meshKernelState.contains(meshKernelId))
{
throw meshkernel::MeshKernelError("The selected mesh kernel id does not exist.");
}

const auto& mesh2d = meshKernelState.at(meshKernelId).m_mesh2d;

if (!mesh2d || mesh2d->GetNumNodes() <= 0)
{
return lastExitCode;
}

const auto propertyValueEnum = static_cast<meshkernel::Mesh2D::Property>(propertyValue);
switch (propertyValueEnum)
{
case meshkernel::Mesh2D::Property::Orthogonality:
{
std::vector<double> values = mesh2d->GetOrthogonality();
if (static_cast<size_t>(geometryList.num_coordinates) < values.size())
{
throw meshkernel::MeshKernelError("GeometryList with wrong dimensions");
}
std::copy(values.begin(), values.end(), geometryList.values);
}
break;
case meshkernel::Mesh2D::Property::EdgeLength:
{
mesh2d->ComputeEdgesLengths();
std::vector<double> values = mesh2d->m_edgeLengths;
if (static_cast<size_t>(geometryList.num_coordinates) < values.size())
{
throw meshkernel::MeshKernelError("GeometryList with wrong dimensions");
}
std::copy(values.begin(), values.end(), geometryList.values);
}
break;
default:
throw meshkernel::MeshKernelError("Property not supported");
}
}
catch (...)
{
lastExitCode = HandleException();
}
return lastExitCode;
}

MKERNEL_API int mkernel_mesh2d_get_property_dimension(int meshKernelId, int propertyValue, int& dimension)
{
lastExitCode = meshkernel::ExitCode::Success;
try
{
if (!meshKernelState.contains(meshKernelId))
{
throw meshkernel::MeshKernelError("The selected mesh kernel id does not exist.");
}

const auto& mesh2d = meshKernelState.at(meshKernelId).m_mesh2d;

if (!mesh2d || mesh2d->GetNumNodes() <= 0)
{
return lastExitCode;
}

const auto propertyValueEnum = static_cast<meshkernel::Mesh2D::Property>(propertyValue);
dimension = -1;
switch (propertyValueEnum)
{
case meshkernel::Mesh2D::Property::Orthogonality:
dimension = static_cast<int>(mesh2d->GetOrthogonality().size());
break;

case meshkernel::Mesh2D::Property::EdgeLength:
mesh2d->ComputeEdgesLengths();
dimension = static_cast<int>(mesh2d->m_edgeLengths.size());
break;
default:
throw meshkernel::MeshKernelError("Property not supported");
}
}
catch (...)
{
lastExitCode = HandleException();
}
return lastExitCode;
}

MKERNEL_API int mkernel_mesh2d_get_smoothness(int meshKernelId, GeometryList& geometryList)
{
lastExitCode = meshkernel::ExitCode::Success;
Expand Down
56 changes: 56 additions & 0 deletions libs/MeshKernelApi/tests/src/Mesh2DTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <gtest/gtest.h>
#include <random>

#include "CartesianApiTestFixture.hpp"
#include "MeshKernel/Parameters.hpp"
#include "MeshKernelApi/BoundingBox.hpp"
#include "MeshKernelApi/Mesh2D.hpp"
Expand Down Expand Up @@ -133,6 +134,61 @@ TEST(Mesh2DTests, Mesh2dApiNodeEdgeDataTest)
}
}

TEST(Mesh2DTests, Mesh2DGetPropertyTest)
{
std::vector<double> nodesX{57.0, 49.1, 58.9, 66.7, 48.8, 65.9, 67.0, 49.1};
std::vector<double> nodesY{23.6, 14.0, 6.9, 16.2, 23.4, 24.0, 7.2, 6.7};

std::vector edges{
0, 1,
1, 2,
2, 3,
0, 3,
1, 4,
0, 4,
0, 5,
3, 5,
3, 6,
2, 6,
2, 7,
1, 7};

meshkernelapi::Mesh2D mesh2d;
mesh2d.edge_nodes = edges.data();
mesh2d.node_x = nodesX.data();
mesh2d.node_y = nodesY.data();
mesh2d.num_nodes = static_cast<int>(nodesX.size());
mesh2d.num_edges = static_cast<int>(edges.size() * 0.5);

int meshKernelId = -1;
auto errorCode = meshkernelapi::mkernel_allocate_state(0, meshKernelId);
ASSERT_EQ(meshkernel::ExitCode::Success, errorCode);
errorCode = mkernel_mesh2d_set(meshKernelId, mesh2d);
ASSERT_EQ(meshkernel::ExitCode::Success, errorCode);

int geometryListDimension = -1;
errorCode = meshkernelapi::mkernel_mesh2d_get_property_dimension(meshKernelId, 0, geometryListDimension);
ASSERT_EQ(meshkernel::ExitCode::Success, errorCode);

// Execute
meshkernelapi::GeometryList propertyvalues{};
propertyvalues.num_coordinates = geometryListDimension;
propertyvalues.geometry_separator = meshkernel::constants::missing::doubleValue;
std::vector<double> values(geometryListDimension);
propertyvalues.values = values.data();
errorCode = mkernel_mesh2d_get_property(meshKernelId, 0, propertyvalues);
ASSERT_EQ(meshkernel::ExitCode::Success, errorCode);

// Assert
EXPECT_EQ(propertyvalues.num_coordinates, 12);
const double tolerance = 1e-4;

EXPECT_NEAR(values[0], 0.055751274056612614, tolerance);
EXPECT_NEAR(values[1], 0.056220640190527582, tolerance);
EXPECT_NEAR(values[2], 0.051193798544321531, tolerance);
EXPECT_NEAR(values[3], 0.056591641726992326, tolerance);
}

TEST(Mesh2DTests, GetPolygonsOfDeletedFaces_WithPolygon_ShouldGetPolygonOfDeletedFaces)
{
// Prepare: set a mesh with two faces sharing an high orthogonality edge. 2 polygon faces should be return
Expand Down

0 comments on commit 90bcb59

Please sign in to comment.