diff --git a/fortran/test/fetch_content_integration/test_tuvx_api.F90 b/fortran/test/fetch_content_integration/test_tuvx_api.F90 index 7dfdddff..3be129ec 100644 --- a/fortran/test/fetch_content_integration/test_tuvx_api.F90 +++ b/fortran/test/fetch_content_integration/test_tuvx_api.F90 @@ -105,6 +105,9 @@ subroutine test_tuvx_solve() grid => grid_t( "foo", "bars", 4, error ) ASSERT( error%is_success() ) + ASSERT_EQ( grid%number_of_sections( error ), 4 ) + ASSERT( error%is_success() ) + call grid%set_edges( edges, error ) ASSERT( error%is_success() ) diff --git a/fortran/tuvx/grid.F90 b/fortran/tuvx/grid.F90 index 202b1b94..db9b9563 100644 --- a/fortran/tuvx/grid.F90 +++ b/fortran/tuvx/grid.F90 @@ -32,6 +32,15 @@ subroutine delete_grid_c(grid, error) bind(C, name="DeleteGrid") type(error_t_c), intent(inout) :: error end subroutine delete_grid_c + function get_grid_num_sections_c(grid, error) & + bind(C, name="GetGridNumSections") + use iso_c_binding, only : c_ptr, c_size_t + use musica_util, only: error_t_c + type(c_ptr), value, intent(in) :: grid + type(error_t_c), intent(inout) :: error + integer(c_size_t) :: get_grid_num_sections_c + end function get_grid_num_sections_c + subroutine set_grid_edges_c(grid, edges, n_edges, error) & bind(C, name="SetGridEdges") use iso_c_binding, only : c_ptr, c_size_t @@ -78,6 +87,8 @@ end subroutine get_grid_midpoints_c type :: grid_t type(c_ptr) :: ptr_ = c_null_ptr contains + ! Returns the number of sections in the grid + procedure :: number_of_sections ! Set grid edges procedure :: set_edges ! Get grid edges @@ -140,6 +151,23 @@ function grid_t_constructor(grid_name, grid_units, number_of_sections, error) & end function grid_t_constructor + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + integer function number_of_sections(this, error) result( n_sections ) + use musica_util, only: error_t, error_t_c + + ! Arguments + class(grid_t), intent(inout) :: this + type(error_t), intent(inout) :: error + + ! Local variables + type(error_t_c) :: error_c + + n_sections = int( get_grid_num_sections_c(this%ptr_, error_c) ) + error = error_t(error_c) + + end function number_of_sections + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine set_edges(this, edges, error) diff --git a/include/musica/tuvx/grid.hpp b/include/musica/tuvx/grid.hpp index bd7a6d3b..9f08c7ac 100644 --- a/include/musica/tuvx/grid.hpp +++ b/include/musica/tuvx/grid.hpp @@ -27,6 +27,11 @@ namespace musica ~Grid(); + /// @brief Return the number of sections in the grid + /// @param error The error struct to indicate success or failure + /// @return The number of sections in the grid + std::size_t GetNumSections(Error *error); + /// @brief Set the edges of the grid /// @param edges The edges of the grid /// @param num_edges the number of edges @@ -83,6 +88,12 @@ namespace musica /// @param error The error struct to indicate success or failure Grid *CreateGrid(const char *grid_name, const char *units, std::size_t num_sections, Error *error); + /// @brief Gets the number of sections in the grid + /// @param grid The grid to get the number of sections from + /// @param error The error struct to indicate success or failure + /// @return The number of sections in the grid + std::size_t GetGridNumSections(Grid *grid, Error *error); + /// @brief Deletes a TUV-x grid instance /// @param grid The grid to delete /// @param error The error struct to indicate success or failure @@ -131,6 +142,7 @@ namespace musica void InternalDeleteGridUpdater(void *updater, int *error_code); std::string InternalGetGridName(void *grid, int *error_code); std::string InternalGetGridUnits(void *grid, int *error_code); + std::size_t InternalGetNumSections(void *grid, int *error_code); void InternalSetEdges(void *grid, double edges[], std::size_t num_edges, int *error_code); void InternalGetEdges(void *grid, double edges[], std::size_t num_edges, int *error_code); void InternalSetMidpoints(void *grid, double midpoints[], std::size_t num_midpoints, int *error_code); diff --git a/src/test/unit/tuvx/tuvx_c_api.cpp b/src/test/unit/tuvx/tuvx_c_api.cpp index 91dbbc93..67d55492 100644 --- a/src/test/unit/tuvx/tuvx_c_api.cpp +++ b/src/test/unit/tuvx/tuvx_c_api.cpp @@ -87,6 +87,8 @@ TEST_F(TuvxCApiTest, CanCreateGrid) Grid* grid = CreateGrid("foo", "m", 2, &error); ASSERT_TRUE(IsSuccess(error)); ASSERT_NE(grid, nullptr); + ASSERT_EQ(GetGridNumSections(grid, &error), 2); + ASSERT_TRUE(IsSuccess(error)); std::vector edges = { 0.0, 100.0, 200.0 }; SetGridEdges(grid, edges.data(), edges.size(), &error); ASSERT_TRUE(IsSuccess(error)); diff --git a/src/tuvx/grid.cpp b/src/tuvx/grid.cpp index 4815f0e2..071b7b0e 100644 --- a/src/tuvx/grid.cpp +++ b/src/tuvx/grid.cpp @@ -32,6 +32,11 @@ namespace musica *error = NoError(); } + std::size_t GetGridNumSections(Grid *grid, Error *error) + { + return grid->GetNumSections(error); + } + void SetGridEdges(Grid *grid, double edges[], std::size_t num_edges, Error *error) { DeleteError(error); @@ -88,6 +93,18 @@ namespace musica updater_ = nullptr; } + std::size_t Grid::GetNumSections(Error *error) + { + int error_code = 0; + std::size_t n_sections = InternalGetNumSections(grid_, &error_code); + if (error_code != 0) + { + *error = Error{ 1, CreateString(MUSICA_ERROR_CATEGORY), CreateString("Failed to get number of sections") }; + return 0; + } + return n_sections; + } + void Grid::SetEdges(double edges[], std::size_t num_edges, Error *error) { int error_code = 0; diff --git a/src/tuvx/interface_grid.F90 b/src/tuvx/interface_grid.F90 index 6e211695..e8f07dc7 100644 --- a/src/tuvx/interface_grid.F90 +++ b/src/tuvx/interface_grid.F90 @@ -115,6 +115,28 @@ subroutine internal_delete_grid_updater(updater, error_code) & end subroutine internal_delete_grid_updater +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + function internal_get_num_sections(grid, error_code) & + bind(C, name="InternalGetNumSections") result(num_sections) + use iso_c_binding, only: c_ptr, c_f_pointer, c_int, c_size_t + use tuvx_grid_from_host, only: grid_from_host_t + + ! arguments + type(c_ptr), value, intent(in) :: grid + integer(kind=c_int), intent(out) :: error_code + + ! output + integer(kind=c_size_t) :: num_sections + + ! variables + type(grid_from_host_t), pointer :: f_grid + + call c_f_pointer(grid, f_grid) + num_sections = f_grid%size( ) + + end function internal_get_num_sections + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine internal_set_edges(grid_updater, edges, num_edges, error_code) &