From 8bb53d9824e2fe77f4af876af019f7caac6d717a Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Thu, 17 Jul 2025 09:50:21 -0600 Subject: [PATCH 01/12] Add new 'atmos_phys' submodule with updated file_reader interface. --- .gitmodules | 5 ++--- src/physics/ncar_ccpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index d93b8303..2d7f5ece 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,8 +19,8 @@ fxDONOTUSEurl = https://github.com/MPAS-Dev/MPAS-Model.git [submodule "ncar-physics"] path = src/physics/ncar_ccpp - url = https://github.com/ESCOMP/atmospheric_physics - fxtag = e92f76351e7f7703fb6d91cb5e76dcbbc6dcb3f2 + url = https://github.com/nusbaume/atmospheric_physics + fxtag = e57e4d2c4f907edaa0c1a500845c0305fb60b0e8 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] @@ -119,4 +119,3 @@ fxtag = v0.1.4 fxrequired = ToplevelRequired fxDONOTUSEurl = https://github.com/NCAR/CUPiD.git - diff --git a/src/physics/ncar_ccpp b/src/physics/ncar_ccpp index e92f7635..e57e4d2c 160000 --- a/src/physics/ncar_ccpp +++ b/src/physics/ncar_ccpp @@ -1 +1 @@ -Subproject commit e92f76351e7f7703fb6d91cb5e76dcbbc6dcb3f2 +Subproject commit e57e4d2c4f907edaa0c1a500845c0305fb60b0e8 From 9656c58b5fc0ba7ae122dc29453fec83b57d25d7 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Fri, 18 Jul 2025 11:48:39 -0600 Subject: [PATCH 02/12] Update PIO CCPP FileIO implementation and unit tests to use allocatable instead of pointer variables. --- .github/workflows/fortran_unit_tests.yml | 1 + .gitmodules | 2 +- src/physics/ncar_ccpp | 2 +- src/physics/utils/pio_reader.F90 | 247 ++++++++++++------ .../fortran/src/pio_reader/test_pio_reader.pf | 72 +++-- 5 files changed, 198 insertions(+), 126 deletions(-) diff --git a/.github/workflows/fortran_unit_tests.yml b/.github/workflows/fortran_unit_tests.yml index c2143ac7..5a274225 100644 --- a/.github/workflows/fortran_unit_tests.yml +++ b/.github/workflows/fortran_unit_tests.yml @@ -5,6 +5,7 @@ on: branches: - development - main + - pio_reader_updates pull_request: workflow_dispatch: diff --git a/.gitmodules b/.gitmodules index 2d7f5ece..95fde3bf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = e57e4d2c4f907edaa0c1a500845c0305fb60b0e8 + fxtag = 6960ce2f8fe0cc45aaf8188f07449028129d5531 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] diff --git a/src/physics/ncar_ccpp b/src/physics/ncar_ccpp index e57e4d2c..6960ce2f 160000 --- a/src/physics/ncar_ccpp +++ b/src/physics/ncar_ccpp @@ -1 +1 @@ -Subproject commit e57e4d2c4f907edaa0c1a500845c0305fb60b0e8 +Subproject commit 6960ce2f8fe0cc45aaf8188f07449028129d5531 diff --git a/src/physics/utils/pio_reader.F90 b/src/physics/utils/pio_reader.F90 index 5a6983df..7db701ec 100644 --- a/src/physics/utils/pio_reader.F90 +++ b/src/physics/utils/pio_reader.F90 @@ -30,20 +30,27 @@ module pio_reader private type(file_handle_t) :: sima_pio_fh !PIO File handle type contains + !File procedures procedure :: open_file => open_netcdf_file procedure :: close_file => close_netcdf_file + + !Integer interfaces procedure :: get_var_int_0d => get_netcdf_var_int_0d procedure :: get_var_int_1d => get_netcdf_var_int_1d procedure :: get_var_int_2d => get_netcdf_var_int_2d procedure :: get_var_int_3d => get_netcdf_var_int_3d procedure :: get_var_int_4d => get_netcdf_var_int_4d procedure :: get_var_int_5d => get_netcdf_var_int_5d + + !Real interfaces procedure :: get_var_real_0d => get_netcdf_var_real_0d procedure :: get_var_real_1d => get_netcdf_var_real_1d procedure :: get_var_real_2d => get_netcdf_var_real_2d procedure :: get_var_real_3d => get_netcdf_var_real_3d procedure :: get_var_real_4d => get_netcdf_var_real_4d procedure :: get_var_real_5d => get_netcdf_var_real_5d + + !Character interfaces procedure :: get_var_char_0d => get_netcdf_var_char_0d procedure :: get_var_char_1d => get_netcdf_var_char_1d procedure :: get_var_char_2d => get_netcdf_var_char_2d @@ -122,7 +129,7 @@ end subroutine close_netcdf_file ! Integer interfaces ! ------------------------------------------------------------------ - subroutine get_netcdf_var_int_0d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_int_0d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -131,11 +138,15 @@ subroutine get_netcdf_var_int_0d(this, varname, var, errmsg, errcode) use pio, only: PIO_NOERR use pio, only: PIO_BCAST_ERROR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - integer, pointer, intent(out) :: var !Integer variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + integer, allocatable, intent(out) :: var !Integer variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -226,7 +237,7 @@ subroutine get_netcdf_var_int_0d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_int_0d - subroutine get_netcdf_var_int_1d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_int_1d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -235,11 +246,15 @@ subroutine get_netcdf_var_int_1d(this, varname, var, errmsg, errcode) use pio, only: PIO_NOERR use pio, only: PIO_BCAST_ERROR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - integer, pointer, intent(out) :: var(:) !Integer variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + integer, allocatable, intent(out) :: var(:) !Integer variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -371,7 +386,7 @@ subroutine get_netcdf_var_int_1d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_int_1d - subroutine get_netcdf_var_int_2d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_int_2d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -380,11 +395,15 @@ subroutine get_netcdf_var_int_2d(this, varname, var, errmsg, errcode) use pio, only: PIO_NOERR use pio, only: PIO_BCAST_ERROR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - integer, pointer, intent(out) :: var(:,:) !Integer variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + integer, allocatable, intent(out) :: var(:,:) !Integer variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -516,7 +535,7 @@ subroutine get_netcdf_var_int_2d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_int_2d - subroutine get_netcdf_var_int_3d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_int_3d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -525,11 +544,15 @@ subroutine get_netcdf_var_int_3d(this, varname, var, errmsg, errcode) use pio, only: PIO_NOERR use pio, only: PIO_BCAST_ERROR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - integer, pointer, intent(out) :: var(:,:,:) !Integer variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + integer, allocatable, intent(out) :: var(:,:,:) !Integer variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -661,7 +684,7 @@ subroutine get_netcdf_var_int_3d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_int_3d - subroutine get_netcdf_var_int_4d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_int_4d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -670,11 +693,15 @@ subroutine get_netcdf_var_int_4d(this, varname, var, errmsg, errcode) use pio, only: PIO_NOERR use pio, only: PIO_BCAST_ERROR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - integer, pointer, intent(out) :: var(:,:,:,:) !Integer variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + integer, allocatable, intent(out) :: var(:,:,:,:) !Integer variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -806,7 +833,7 @@ subroutine get_netcdf_var_int_4d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_int_4d - subroutine get_netcdf_var_int_5d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_int_5d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -815,11 +842,15 @@ subroutine get_netcdf_var_int_5d(this, varname, var, errmsg, errcode) use pio, only: PIO_NOERR use pio, only: PIO_BCAST_ERROR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - integer, pointer, intent(out) :: var(:,:,:,:,:) !Integer variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + integer, allocatable, intent(out) :: var(:,:,:,:,:) !Integer variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -956,7 +987,7 @@ end subroutine get_netcdf_var_int_5d ! Real interfaces ! ------------------------------------------------------------------ - subroutine get_netcdf_var_real_0d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_real_0d(this, varname, var, errmsg, errcode, start, count) use ccpp_kinds, only: kind_phys use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen @@ -968,10 +999,14 @@ subroutine get_netcdf_var_real_0d(this, varname, var, errmsg, errcode) class(pio_reader_t), intent(in) :: this character(len=*), intent(in) :: varname - real(kind_phys), pointer, intent(out) :: var !Real variable that file data will be read to. + real(kind_phys), allocatable, intent(out) :: var !Real variable that file data will be read to. integer, intent(out) :: errcode !Error code character(len=*), intent(out) :: errmsg !Error message + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension + type(file_desc_t) :: pio_file_handle !File handle type used by PIO character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code @@ -1060,7 +1095,7 @@ subroutine get_netcdf_var_real_0d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_real_0d - subroutine get_netcdf_var_real_1d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_real_1d(this, varname, var, errmsg, errcode, start, count) use ccpp_kinds, only: kind_phys use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen @@ -1072,10 +1107,14 @@ subroutine get_netcdf_var_real_1d(this, varname, var, errmsg, errcode) class(pio_reader_t), intent(in) :: this character(len=*), intent(in) :: varname - real(kind_phys), pointer, intent(out) :: var(:) !Real variable that file data will be read to. + real(kind_phys), allocatable, intent(out) :: var(:) !Real variable that file data will be read to. integer, intent(out) :: errcode !Error code character(len=*), intent(out) :: errmsg !Error message + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension + type(file_desc_t) :: pio_file_handle !File handle type used by PIO character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code @@ -1205,7 +1244,7 @@ subroutine get_netcdf_var_real_1d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_real_1d - subroutine get_netcdf_var_real_2d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_real_2d(this, varname, var, errmsg, errcode, start, count) use ccpp_kinds, only: kind_phys use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen @@ -1217,10 +1256,14 @@ subroutine get_netcdf_var_real_2d(this, varname, var, errmsg, errcode) class(pio_reader_t), intent(in) :: this character(len=*), intent(in) :: varname - real(kind_phys), pointer, intent(out) :: var(:,:) !Real variable that file data will be read to. + real(kind_phys), allocatable, intent(out) :: var(:,:) !Real variable that file data will be read to. integer, intent(out) :: errcode !Error code character(len=*), intent(out) :: errmsg !Error message + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension + type(file_desc_t) :: pio_file_handle !File handle type used by PIO character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code @@ -1350,7 +1393,7 @@ subroutine get_netcdf_var_real_2d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_real_2d - subroutine get_netcdf_var_real_3d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_real_3d(this, varname, var, errmsg, errcode, start, count) use ccpp_kinds, only: kind_phys use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen @@ -1362,10 +1405,14 @@ subroutine get_netcdf_var_real_3d(this, varname, var, errmsg, errcode) class(pio_reader_t), intent(in) :: this character(len=*), intent(in) :: varname - real(kind_phys), pointer, intent(out) :: var(:,:,:) !Real variable that file data will be read to. + real(kind_phys), allocatable, intent(out) :: var(:,:,:) !Real variable that file data will be read to. integer, intent(out) :: errcode !Error code character(len=*), intent(out) :: errmsg !Error message + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension + type(file_desc_t) :: pio_file_handle !File handle type used by PIO character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code @@ -1495,7 +1542,7 @@ subroutine get_netcdf_var_real_3d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_real_3d - subroutine get_netcdf_var_real_4d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_real_4d(this, varname, var, errmsg, errcode, start, count) use ccpp_kinds, only: kind_phys use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen @@ -1507,10 +1554,14 @@ subroutine get_netcdf_var_real_4d(this, varname, var, errmsg, errcode) class(pio_reader_t), intent(in) :: this character(len=*), intent(in) :: varname - real(kind_phys), pointer, intent(out) :: var(:,:,:,:) !Real variable that file data will be read to. + real(kind_phys), allocatable, intent(out) :: var(:,:,:,:) !Real variable that file data will be read to. integer, intent(out) :: errcode !Error code character(len=*), intent(out) :: errmsg !Error message + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension + type(file_desc_t) :: pio_file_handle !File handle type used by PIO character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code @@ -1640,7 +1691,7 @@ subroutine get_netcdf_var_real_4d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_real_4d - subroutine get_netcdf_var_real_5d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_real_5d(this, varname, var, errmsg, errcode, start, count) use ccpp_kinds, only: kind_phys use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen @@ -1652,10 +1703,14 @@ subroutine get_netcdf_var_real_5d(this, varname, var, errmsg, errcode) class(pio_reader_t), intent(in) :: this character(len=*), intent(in) :: varname - real(kind_phys), pointer, intent(out) :: var(:,:,:,:,:) !Real variable that file data will be read to. + real(kind_phys), allocatable, intent(out) :: var(:,:,:,:,:) !Real variable that file data will be read to. integer, intent(out) :: errcode !Error code character(len=*), intent(out) :: errmsg !Error message + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension + type(file_desc_t) :: pio_file_handle !File handle type used by PIO character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code @@ -1790,7 +1845,7 @@ end subroutine get_netcdf_var_real_5d ! Character interfaces ! ------------------------------------------------------------------ - subroutine get_netcdf_var_char_0d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_char_0d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -1800,11 +1855,15 @@ subroutine get_netcdf_var_char_0d(this, varname, var, errmsg, errcode) use pio, only: PIO_BCAST_ERROR use pio_types, only: PIO_CHAR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - character(len=:), pointer, intent(out) :: var !Character variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + character(len=:), allocatable, intent(out) :: var !Character variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -1955,7 +2014,7 @@ subroutine get_netcdf_var_char_0d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_char_0d - subroutine get_netcdf_var_char_1d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_char_1d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -1965,11 +2024,15 @@ subroutine get_netcdf_var_char_1d(this, varname, var, errmsg, errcode) use pio, only: PIO_BCAST_ERROR use pio_types, only: PIO_CHAR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - character(len=:), pointer, intent(out) :: var(:) !Character variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + character(len=:), allocatable, intent(out) :: var(:) !Character variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -2120,7 +2183,7 @@ subroutine get_netcdf_var_char_1d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_char_1d - subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -2130,11 +2193,15 @@ subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode) use pio, only: PIO_BCAST_ERROR use pio_types, only: PIO_CHAR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - character(len=:), pointer, intent(out) :: var(:,:) !Character variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + character(len=:), allocatable, intent(out) :: var(:,:) !Character variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -2285,7 +2352,7 @@ subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_char_2d - subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -2295,11 +2362,15 @@ subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode) use pio, only: PIO_BCAST_ERROR use pio_types, only: PIO_CHAR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - character(len=:), pointer, intent(out) :: var(:,:,:) !Character variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + character(len=:), allocatable, intent(out) :: var(:,:,:) !Character variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -2450,7 +2521,7 @@ subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_char_3d - subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -2460,11 +2531,15 @@ subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode) use pio, only: PIO_BCAST_ERROR use pio_types, only: PIO_CHAR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - character(len=:), pointer, intent(out) :: var(:,:,:,:) !Character variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + character(len=:), allocatable, intent(out) :: var(:,:,:,:) !Character variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO @@ -2616,7 +2691,7 @@ subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode) errmsg = '' end subroutine get_netcdf_var_char_4d - subroutine get_netcdf_var_char_5d(this, varname, var, errmsg, errcode) + subroutine get_netcdf_var_char_5d(this, varname, var, errmsg, errcode, start, count) use pio, only: pio_inq_varid use pio, only: pio_inq_dimlen use pio, only: pio_inquire_variable @@ -2626,11 +2701,15 @@ subroutine get_netcdf_var_char_5d(this, varname, var, errmsg, errcode) use pio, only: PIO_BCAST_ERROR use pio_types, only: PIO_CHAR - class(pio_reader_t), intent(in) :: this - character(len=*), intent(in) :: varname - character(len=:), pointer, intent(out) :: var(:,:,:,:,:) !Character variable that file data will be read to. - integer, intent(out) :: errcode !Error code - character(len=*), intent(out) :: errmsg !Error message + class(pio_reader_t), intent(in) :: this + character(len=*), intent(in) :: varname + character(len=:), allocatable, intent(out) :: var(:,:,:,:,:) !Character variable that file data will be read to. + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Optional arguments for reading a subset of the variable + integer, optional, intent(in) :: start(:) !Start indices for each dimension + integer, optional, intent(in) :: count(:) !Number of elements to read for each dimension !Local variables: type(file_desc_t) :: pio_file_handle !File handle type used by PIO diff --git a/test/unit/fortran/src/pio_reader/test_pio_reader.pf b/test/unit/fortran/src/pio_reader/test_pio_reader.pf index 4fe1dabd..a338ab78 100644 --- a/test/unit/fortran/src/pio_reader/test_pio_reader.pf +++ b/test/unit/fortran/src/pio_reader/test_pio_reader.pf @@ -185,7 +185,7 @@ subroutine test_pio_reader_1d_int_read() character(len=256) :: errmsg !Variable to be read: - integer, pointer :: pressure(:) + integer, allocatable :: pressure(:) ! File name for testing: @@ -209,7 +209,7 @@ subroutine test_pio_reader_1d_int_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assertAssociated(pressure) + @assertTrue(allocated(pressure)) @assertEqual(59, size(pressure)) ! Check that the variable's values are correct: @@ -217,7 +217,6 @@ subroutine test_pio_reader_1d_int_read() ! Perform test cleanup: deallocate(pressure) - nullify(pressure) call reader%close_file(errmsg, errcode) deallocate(reader) @@ -241,7 +240,7 @@ subroutine test_pio_reader_2d_int_read() character(len=256) :: errmsg !Variable to be read: - integer, pointer :: minor_limits_gpt_lower(:,:) + integer, allocatable :: minor_limits_gpt_lower(:,:) ! File name for testing: ! NOTE: This specific file is added during the Github Actions workflow. @@ -263,7 +262,7 @@ subroutine test_pio_reader_2d_int_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assertAssociated(minor_limits_gpt_lower) + @assertTrue(allocated(minor_limits_gpt_lower)) @assertEqual(2, size(minor_limits_gpt_lower, dim=1)) @assertEqual(34, size(minor_limits_gpt_lower, dim=2)) @@ -273,7 +272,6 @@ subroutine test_pio_reader_2d_int_read() ! Perform test cleanup: deallocate(minor_limits_gpt_lower) - nullify(minor_limits_gpt_lower) call reader%close_file(errmsg, errcode) deallocate(reader) @@ -296,7 +294,7 @@ subroutine test_pio_reader_3d_int_read() character(len=256) :: errmsg ! Variable to be read: - integer, pointer :: key_species(:,:,:) + integer, allocatable :: key_species(:,:,:) ! File name for testing: ! NOTE: This specific file is added during the Github Actions workflow. @@ -318,7 +316,7 @@ subroutine test_pio_reader_3d_int_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assertAssociated(key_species) + @assertTrue(allocated(key_species)) @assertEqual(2, size(key_species, dim=1)) @assertEqual(2, size(key_species, dim=2)) @assertEqual(14, size(key_species, dim=3)) @@ -330,7 +328,6 @@ subroutine test_pio_reader_3d_int_read() ! Perform test cleanup: deallocate(key_species) - nullify(key_species) call reader%close_file(errmsg, errcode) deallocate(reader) @@ -354,7 +351,7 @@ subroutine test_pio_reader_1d_char_read() character(len=256) :: errmsg ! Variable to be read: - character(len=:), pointer :: gas_names(:) + character(len=:), allocatable :: gas_names(:) ! File name for testing: ! NOTE: This specific file is added during the Github Actions workflow. @@ -376,7 +373,7 @@ subroutine test_pio_reader_1d_char_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assertAssociated(gas_names) + @assertTrue(allocated(gas_names)) @assertEqual(32, len(gas_names)) @assertEqual(19, size(gas_names)) @@ -403,7 +400,6 @@ subroutine test_pio_reader_1d_char_read() ! Perform test cleanup: deallocate(gas_names) - nullify(gas_names) call reader%close_file(errmsg, errcode) deallocate(reader) @@ -429,7 +425,7 @@ subroutine test_pio_reader_0d_real_read() character(len=256) :: errmsg ! Variable to be read: - real(kind_phys), pointer :: press_ref_trop + real(kind_phys), allocatable :: press_ref_trop ! Variable value to compare against: real(kind_phys), parameter :: press_ref_trop_value = 9948.43156419_kind_phys @@ -454,14 +450,13 @@ subroutine test_pio_reader_0d_real_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assertAssociated(press_ref_trop) + @assertTrue(allocated(press_ref_trop)) ! Check that the variable's value is correct: @assertEqual(press_ref_trop_value, press_ref_trop, tolerance=1.0e-7) ! Perform test cleanup: - deallocate(press_ref_trop) - nullify(press_ref_trop) + deallocate(press_ref_trop call reader%close_file(errmsg, errcode) deallocate(reader) @@ -487,7 +482,7 @@ subroutine test_pio_reader_1d_real_read() character(len=256) :: errmsg ! Variable to be read: - real(kind_phys), pointer :: press_ref(:) + real(kind_phys), allocatable :: press_ref(:) ! Variable value to compare against: real(kind_phys), parameter :: sum_press_ref = 604970.2016763_kind_phys @@ -512,7 +507,7 @@ subroutine test_pio_reader_1d_real_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assertAssociated(press_ref) + @assertTrue(allocated(press_ref)) @assertEqual(59, size(press_ref)) ! Check that the variable's values are correct: @@ -520,7 +515,6 @@ subroutine test_pio_reader_1d_real_read() ! Perform test cleanup: deallocate(press_ref) - nullify(press_ref) call reader%close_file(errmsg, errcode) deallocate(reader) @@ -546,7 +540,7 @@ subroutine test_pio_reader_2d_real_read() character(len=256) :: errmsg ! Variable to be read: - real(kind_phys), pointer :: bnd_limits_wavenumber(:,:) + real(kind_phys), allocatable :: bnd_limits_wavenumber(:,:) ! File name for testing: ! NOTE: This specific file is added during the Github Actions workflow. @@ -572,7 +566,7 @@ subroutine test_pio_reader_2d_real_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assertAssociated(bnd_limits_wavenumber) + @assertTrue(allocated(bnd_limits_wavenumber)) @assertEqual(2, size(bnd_limits_wavenumber, dim=1)) @assertEqual(14, size(bnd_limits_wavenumber, dim=2)) @@ -583,7 +577,6 @@ subroutine test_pio_reader_2d_real_read() ! Perform test cleanup: deallocate(bnd_limits_wavenumber) - nullify(bnd_limits_wavenumber) call reader%close_file(errmsg, errcode) deallocate(reader) @@ -608,7 +601,7 @@ subroutine test_pio_reader_3d_real_read() character(len=256) :: errmsg ! Variable to be read: - real(kind_phys), pointer :: vmr_ref(:,:,:) + real(kind_phys), allocatable :: vmr_ref(:,:,:) ! File name for testing: ! NOTE: This specific file is added during the Github Actions workflow. @@ -636,7 +629,7 @@ subroutine test_pio_reader_3d_real_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assertAssociated(vmr_ref) + @assertTrue(allocated(vmr_ref)) @assertEqual(2, size(vmr_ref, dim=1)) @assertEqual(20, size(vmr_ref, dim=2)) @assertEqual(14, size(vmr_ref, dim=3)) @@ -649,7 +642,6 @@ subroutine test_pio_reader_3d_real_read() ! Perform test cleanup: deallocate(vmr_ref) - nullify(vmr_ref) call reader%close_file(errmsg, errcode) deallocate(reader) @@ -679,8 +671,8 @@ subroutine test_pio_reader_4d_real_read_with_dims() character(len=256) :: errmsg ! Variable to be read: - !real(kind_phys), pointer :: aero_salt_tbl(:,:,:,:) - real(kind_phys), pointer :: kmajor(:,:,:,:) + !real(kind_phys), allocatable :: aero_salt_tbl(:,:,:,:) + real(kind_phys), allocatable :: kmajor(:,:,:,:) ! File name for testing: ! NOTE: This specific file is added during the Github Actions workflow. @@ -717,13 +709,14 @@ subroutine test_pio_reader_4d_real_read_with_dims() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - !@assertTrue(associated(aero_salt_tbl)) + + !@assertTrue(allocated(aero_salt_tbl)) !@assertTrue(size(aero_salt_tbl, dim=1) == 3) !@assertTrue(size(aero_salt_tbl, dim=2) == 36) !@assertTrue(size(aero_salt_tbl, dim=3) == 5) !@assertTrue(size(aero_salt_tbl, dim=4) == 14) - @assertAssociated(kmajor) + @assertTrue(allocated(kmajor)) @assertEqual(112, size(kmajor, dim=1)) @assertEqual(9, size(kmajor, dim=2)) @assertEqual(60, size(kmajor, dim=3)) @@ -751,7 +744,6 @@ subroutine test_pio_reader_4d_real_read_with_dims() ! Perform test cleanup: !deallocate(aero_salt_tbl) deallocate(kmajor) - nullify(kmajor) call reader%close_file(errmsg, errcode) deallocate(reader) @@ -783,7 +775,7 @@ subroutine test_pio_reader_int_get_var_file_not_opened_err() character(len=256) :: errmsg !Variable to be read: - integer, pointer :: pressure(:) + integer, allocatable :: pressure(:) ! Expected error message: character(len=*), parameter :: expected_err_msg = & @@ -824,7 +816,7 @@ subroutine test_pio_reader_char_get_var_file_not_opened_err() character(len=256) :: errmsg !Variable to be read: - character(len=:), pointer :: gas_names(:) + character(len=:), allocatable :: gas_names(:) ! Expected error message: character(len=*), parameter :: expected_err_msg = & @@ -866,7 +858,7 @@ subroutine test_pio_reader_real_get_var_file_not_opened_err() character(len=256) :: errmsg !Variable to be read: - real(kind_phys), pointer :: press_ref(:) + real(kind_phys), allocatable :: press_ref(:) ! Expected error message: character(len=*), parameter :: expected_err_msg = & @@ -910,7 +902,7 @@ subroutine test_pio_reader_get_var_open_close_err() character(len=256) :: errmsg !Variable to be read: - integer, pointer :: pressure(:) + integer, allocatable :: pressure(:) character(len=*), parameter :: fname = & "../../../rrtmgp-data/rrtmgp-gas-sw-g112.nc" @@ -959,7 +951,7 @@ subroutine test_pio_reader_int_get_var_missing_var() character(len=256) :: errmsg !Variable to be read: - integer, pointer :: missing_var(:) + integer, allocatable :: missing_var(:) character(len=*), parameter :: fname = & "../../../rrtmgp-data/rrtmgp-gas-sw-g112.nc" @@ -1007,7 +999,7 @@ subroutine test_pio_reader_char_get_var_missing_var() character(len=256) :: errmsg !Variable to be read: - character(len=:), pointer :: missing_var(:) + character(len=:), allocatable :: missing_var(:) character(len=*), parameter :: fname = & "../../../rrtmgp-data/rrtmgp-gas-sw-g112.nc" @@ -1057,7 +1049,7 @@ subroutine test_pio_reader_real_get_var_missing_var() character(len=256) :: errmsg !Variable to be read: - real(kind_phys), pointer :: missing_var(:) + real(kind_phys), allocatable :: missing_var(:) character(len=*), parameter :: fname = & "../../../rrtmgp-data/rrtmgp-gas-sw-g112.nc" @@ -1105,7 +1097,7 @@ subroutine test_pio_reader_int_get_var_bad_rank() character(len=256) :: errmsg !Variable to be read: - integer, pointer :: pressure(:,:) + integer, allocatable :: pressure(:,:) character(len=*), parameter :: fname = & "../../../rrtmgp-data/rrtmgp-gas-sw-g112.nc" @@ -1153,7 +1145,7 @@ subroutine test_pio_reader_char_get_var_bad_rank() character(len=256) :: errmsg !Variable to be read: - character(len=:), pointer :: gas_names(:,:) + character(len=:), allocatable :: gas_names(:,:) character(len=*), parameter :: fname = & "../../../rrtmgp-data/rrtmgp-gas-sw-g112.nc" @@ -1203,7 +1195,7 @@ subroutine test_pio_reader_real_get_var_bad_rank() character(len=256) :: errmsg ! Variable to be read: - real(kind_phys), pointer :: press_ref(:,:) + real(kind_phys), allocatable :: press_ref(:,:) character(len=*), parameter :: fname = & "../../../rrtmgp-data/rrtmgp-gas-sw-g112.nc" From 6cac1c65b30bcf77ae17eaed882d520c9091bec0 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Fri, 18 Jul 2025 11:54:49 -0600 Subject: [PATCH 03/12] Fix syntax error in file reader unit test routines. --- test/unit/fortran/src/pio_reader/test_pio_reader.pf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/fortran/src/pio_reader/test_pio_reader.pf b/test/unit/fortran/src/pio_reader/test_pio_reader.pf index a338ab78..b10a7f7e 100644 --- a/test/unit/fortran/src/pio_reader/test_pio_reader.pf +++ b/test/unit/fortran/src/pio_reader/test_pio_reader.pf @@ -456,7 +456,7 @@ subroutine test_pio_reader_0d_real_read() @assertEqual(press_ref_trop_value, press_ref_trop, tolerance=1.0e-7) ! Perform test cleanup: - deallocate(press_ref_trop + deallocate(press_ref_trop) call reader%close_file(errmsg, errcode) deallocate(reader) From b61c356f51280fa8c115700e245339bedfe278e8 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Wed, 23 Jul 2025 10:00:37 -0600 Subject: [PATCH 04/12] Refactor dimension size acquisition for integer and real interfaces. --- src/physics/utils/pio_reader.F90 | 736 ++++++------------------------- 1 file changed, 124 insertions(+), 612 deletions(-) diff --git a/src/physics/utils/pio_reader.F90 b/src/physics/utils/pio_reader.F90 index 7db701ec..19c722ac 100644 --- a/src/physics/utils/pio_reader.F90 +++ b/src/physics/utils/pio_reader.F90 @@ -261,11 +261,9 @@ subroutine get_netcdf_var_int_1d(this, varname, var, errmsg, errcode, start, cou character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + integer, parameter :: var_ndims = 1 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -294,69 +292,14 @@ subroutine get_netcdf_var_int_1d(this, varname, var, errmsg, errcode, start, cou return end if - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 1) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension size - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + !Get variable dimension sizes: + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data: allocate(var(dim_sizes(1)), stat=errcode, errmsg=errmsg) @@ -410,11 +353,9 @@ subroutine get_netcdf_var_int_2d(this, varname, var, errmsg, errcode, start, cou character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + integer, parameter :: var_ndims = 2 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -443,69 +384,14 @@ subroutine get_netcdf_var_int_2d(this, varname, var, errmsg, errcode, start, cou return end if - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 2) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension sizes - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + !Get variable dimension sizes: + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data: allocate(var(dim_sizes(1), dim_sizes(2)), stat=errcode, errmsg=errmsg) @@ -559,11 +445,9 @@ subroutine get_netcdf_var_int_3d(this, varname, var, errmsg, errcode, start, cou character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + integer, parameter :: var_ndims = 3 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -592,69 +476,14 @@ subroutine get_netcdf_var_int_3d(this, varname, var, errmsg, errcode, start, cou return end if - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 3) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data: allocate(var(dim_sizes(1), dim_sizes(2), dim_sizes(3)), stat=errcode, errmsg=errmsg) @@ -712,7 +541,7 @@ subroutine get_netcdf_var_int_4d(this, varname, var, errmsg, errcode, start, cou integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + integer, parameter :: var_ndims = 4 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -741,69 +570,14 @@ subroutine get_netcdf_var_int_4d(this, varname, var, errmsg, errcode, start, cou return end if - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 4) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data: allocate(var(dim_sizes(1), dim_sizes(2), dim_sizes(3), dim_sizes(4)), stat=errcode, errmsg=errmsg) @@ -857,11 +631,9 @@ subroutine get_netcdf_var_int_5d(this, varname, var, errmsg, errcode, start, cou character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + integer, parameter :: var_ndims = 5 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -890,69 +662,14 @@ subroutine get_netcdf_var_int_5d(this, varname, var, errmsg, errcode, start, cou return end if - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 5) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data: allocate(var(dim_sizes(1), dim_sizes(2), dim_sizes(3), dim_sizes(4), dim_sizes(5)), & @@ -1119,11 +836,8 @@ subroutine get_netcdf_var_real_1d(this, varname, var, errmsg, errcode, start, co character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable !---------------------- !Check if file is open: @@ -1152,69 +866,14 @@ subroutine get_netcdf_var_real_1d(this, varname, var, errmsg, errcode, start, co return end if - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 1) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, 1, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data: allocate(var(dim_sizes(1)), stat=errcode, errmsg=errmsg) @@ -1268,11 +927,8 @@ subroutine get_netcdf_var_real_2d(this, varname, var, errmsg, errcode, start, co character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable !---------------------- !Check if file is open: @@ -1298,71 +954,16 @@ subroutine get_netcdf_var_real_2d(this, varname, var, errmsg, errcode, start, co !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 2) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do + return + end if + + !Get variable dimension sizes: + call get_dim_sizes(varname, 2, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then + !Reset PIO back to original error handling method: + call pio_seterrorhandling(pio_file_handle, err_handling) + return + end if !Now attempt to allocate and initialize variable, and !read-in the NetCDF data: @@ -1417,11 +1018,8 @@ subroutine get_netcdf_var_real_3d(this, varname, var, errmsg, errcode, start, co character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable !---------------------- !Check if file is open: @@ -1450,71 +1048,16 @@ subroutine get_netcdf_var_real_3d(this, varname, var, errmsg, errcode, start, co return end if - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 3) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, 3, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - - !Now attempt to allocate and initialize variable, and - !read-in the NetCDF data: + !Now attempt to allocate and initialize the variable, + !and read-in the NetCDF data: allocate(var(dim_sizes(1), dim_sizes(2), dim_sizes(3)), stat=errcode, errmsg=errmsg) if(errcode /= 0) then !Reset PIO back to original error handling method: @@ -1566,11 +1109,8 @@ subroutine get_netcdf_var_real_4d(this, varname, var, errmsg, errcode, start, co character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable !---------------------- !Check if file is open: @@ -1599,69 +1139,14 @@ subroutine get_netcdf_var_real_4d(this, varname, var, errmsg, errcode, start, co return end if - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 4) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, 4, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data: allocate(var(dim_sizes(1), dim_sizes(2), dim_sizes(3), dim_sizes(4)), stat=errcode, errmsg=errmsg) @@ -1715,11 +1200,8 @@ subroutine get_netcdf_var_real_5d(this, varname, var, errmsg, errcode, start, co character(len=cl) :: file_path !Path to NetCDF file integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable !---------------------- !Check if file is open: @@ -1748,71 +1230,16 @@ subroutine get_netcdf_var_real_5d(this, varname, var, errmsg, errcode, start, co return end if - !Get number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - errcode = 0 - if(ndims /= 5) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, 5, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - - !Now attempt to allocate and initialize variable, and - !read-in the NetCDF data: + !Now attempt to allocate and initialize the variable, + !and read-in the NetCDF data: allocate(var(dim_sizes(1), dim_sizes(2), dim_sizes(3), dim_sizes(4), dim_sizes(5)), & stat=errcode, errmsg=errmsg) if(errcode /= 0) then @@ -2861,6 +2288,10 @@ subroutine get_netcdf_var_char_5d(this, varname, var, errmsg, errcode, start, co errmsg = '' end subroutine get_netcdf_var_char_5d + ! ------------------------------------------------------------------ + ! Helper routines (not externally accessible) + ! ------------------------------------------------------------------ + subroutine get_pio_errmsg(caller_errcode, varname, errcode, errmsg, file_msg) !Set error message based off PIO error code, !and then reset PIO error code to caller-specified @@ -2909,4 +2340,85 @@ subroutine get_pio_errmsg(caller_errcode, varname, errcode, errmsg, file_msg) end if end subroutine get_pio_errmsg + subroutine get_dim_sizes(varname, var_rank, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + !Extract the dimension sizes for a NetCDF + !variable given a variable ID, and + !return a new 1-D array with the variable + !dimension sizes. + + use pio, only: pio_inq_dimlen + use pio, only: pio_inquire_variable + use pio, only: PIO_NOERR + + !Input variables: + character(len=*), intent(in) :: varname !Name of NetCDF variable + integer, intent(in) :: var_rank !Rank (number of dims) of NetCDF variable + integer, intent(in) :: var_id !Variable ID for NetCDF variable + type(file_desc_t), intent(in) :: pio_file_handle !File handle type used by PIO + + !Output variables: + integer, allocatable, intent(out) :: dim_sizes(:) !Variable dimension sizes + integer, intent(out) :: errcode !Error code + character(len=*), intent(out) :: errmsg !Error message + + !Local variables: + integer :: ndims !Number of NetCDF variable dimensions + integer, allocatable :: dim_ids(:) !Variable dimension IDs + + integer :: i !loop control variable + + !Initialize error code and message: + errcode = 0 + errmsg = '' + + !Get number of variable dimensions on file: + errcode = pio_inquire_variable(pio_file_handle, var_id, ndims=ndims) + if(errcode /= PIO_NOERR) then + !Extract error message from PIO: + call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) + return + end if + + !Check that the variable rank as specified by the caller + !matches what is found on the NetCDF file: + errcode = 0 + if(ndims /= var_rank) then + errcode = bad_var_rank_err + errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" + return + end if + + !Get variable dimension sizes: + !Allocate NetCDF variable dimension ID array: + allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) + if(errcode /= 0) then + return + end if + + !Get variable dimension IDs: + errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) + if(errcode /= PIO_NOERR) then + !Extract error message from PIO: + call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) + return + end if + + !Allocate NetCDF variable dimension sizes array: + allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) + if(errcode /= 0) then + return + end if + + !Get dimension sizes: + do i = 1, ndims + errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) + if(errcode /= PIO_NOERR) then + !Extract error message from PIO: + call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) + return + end if + end do + + end subroutine get_dim_sizes + end module pio_reader From b17d99324dcf23dc2bd25e244470650750602da0 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Wed, 23 Jul 2025 12:17:55 -0600 Subject: [PATCH 05/12] Refactor dimension acquisition for character interfaces. --- src/physics/utils/pio_reader.F90 | 461 +++++++------------------------ 1 file changed, 96 insertions(+), 365 deletions(-) diff --git a/src/physics/utils/pio_reader.F90 b/src/physics/utils/pio_reader.F90 index 19c722ac..3bd86cef 100644 --- a/src/physics/utils/pio_reader.F90 +++ b/src/physics/utils/pio_reader.F90 @@ -154,10 +154,7 @@ subroutine get_netcdf_var_int_0d(this, varname, var, errmsg, errcode, start, cou integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - - integer :: i !loop control variable !---------------------- !Check if file is open: @@ -729,10 +726,7 @@ subroutine get_netcdf_var_real_0d(this, varname, var, errmsg, errcode, start, co integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - - integer :: i !loop control variable !---------------------- !Check if file is open: @@ -838,6 +832,7 @@ subroutine get_netcdf_var_real_1d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes + integer, parameter :: var_ndims = 1 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -867,7 +862,7 @@ subroutine get_netcdf_var_real_1d(this, varname, var, errmsg, errcode, start, co end if !Get variable dimension sizes: - call get_dim_sizes(varname, 1, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) @@ -929,6 +924,7 @@ subroutine get_netcdf_var_real_2d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes + integer, parameter :: var_ndims = 2 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -958,7 +954,7 @@ subroutine get_netcdf_var_real_2d(this, varname, var, errmsg, errcode, start, co end if !Get variable dimension sizes: - call get_dim_sizes(varname, 2, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) @@ -1020,6 +1016,7 @@ subroutine get_netcdf_var_real_3d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes + integer, parameter :: var_ndims = 3 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -1049,7 +1046,7 @@ subroutine get_netcdf_var_real_3d(this, varname, var, errmsg, errcode, start, co end if !Get variable dimension sizes: - call get_dim_sizes(varname, 3, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) @@ -1111,6 +1108,7 @@ subroutine get_netcdf_var_real_4d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes + integer, parameter :: var_ndims = 4 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -1140,7 +1138,7 @@ subroutine get_netcdf_var_real_4d(this, varname, var, errmsg, errcode, start, co end if !Get variable dimension sizes: - call get_dim_sizes(varname, 4, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) @@ -1202,6 +1200,7 @@ subroutine get_netcdf_var_real_5d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes + integer, parameter :: var_ndims = 5 !Number of expected variable dimensions on NetCDF file !---------------------- !Check if file is open: @@ -1231,7 +1230,7 @@ subroutine get_netcdf_var_real_5d(this, varname, var, errmsg, errcode, start, co end if !Get variable dimension sizes: - call get_dim_sizes(varname, 5, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) @@ -1298,10 +1297,17 @@ subroutine get_netcdf_var_char_0d(this, varname, var, errmsg, errcode, start, co integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID integer :: nc_type !NetCDF variable type - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + + !NOTE: NetCDF supports both character arrays and string-type + !data depending on the NetCDF version, so the dimensions + !might be one larger than the actual array size if it + !includes the character length as a dimension as well. + !Ideally the actual type would be checked and handled + !differently, but for now just assume a character array + !and check for ndims = rank+1 + integer, parameter :: var_ndims = 1 !Number of expected variable dimensions on NetCDF file + !---------------------- !Check if file is open: if(.not.this%sima_pio_fh%is_file_open) then @@ -1329,8 +1335,8 @@ subroutine get_netcdf_var_char_0d(this, varname, var, errmsg, errcode, start, co return end if - !Get variable type and number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type, ndims=ndims) + !Get variable type on file: + errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type) if(errcode /= PIO_NOERR) then !Extract error message from PIO: call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) @@ -1350,66 +1356,14 @@ subroutine get_netcdf_var_char_0d(this, varname, var, errmsg, errcode, start, co return end if - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - - !NOTE: NetCDF supports both character arrays and string-type - !data depending on the NetCDF version, so the dimensions - !might be one larger than the actual array size if it - !includes the character length as a dimension as well. - !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 - errcode = 0 - if(ndims /= 1) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data. Note that the first dimenstion !is the length of the character array, so need to start @@ -1467,10 +1421,17 @@ subroutine get_netcdf_var_char_1d(this, varname, var, errmsg, errcode, start, co integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID integer :: nc_type !NetCDF variable type - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + + !NOTE: NetCDF supports both character arrays and string-type + !data depending on the NetCDF version, so the dimensions + !might be one larger than the actual array size if it + !includes the character length as a dimension as well. + !Ideally the actual type would be checked and handled + !differently, but for now just assume a character array + !and check for ndims = rank+1 + integer, parameter :: var_ndims = 2 !Number of expected variable dimensions on NetCDF file + !---------------------- !Check if file is open: if(.not.this%sima_pio_fh%is_file_open) then @@ -1498,8 +1459,8 @@ subroutine get_netcdf_var_char_1d(this, varname, var, errmsg, errcode, start, co return end if - !Get variable type and number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type, ndims=ndims) + !Get variable type on file: + errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type) if(errcode /= PIO_NOERR) then !Extract error message from PIO: call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) @@ -1519,66 +1480,14 @@ subroutine get_netcdf_var_char_1d(this, varname, var, errmsg, errcode, start, co return end if - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - - !NOTE: NetCDF supports both character arrays and string-type - !data depending on the NetCDF version, so the dimensions - !might be one larger than the actual array size if it - !includes the character length as a dimension as well. - !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 - errcode = 0 - if(ndims /= 2) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data. Note that the first dimenstion !is the length of the character array, so need to start @@ -1636,10 +1545,17 @@ subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode, start, co integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID integer :: nc_type !NetCDF variable type - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + + !NOTE: NetCDF supports both character arrays and string-type + !data depending on the NetCDF version, so the dimensions + !might be one larger than the actual array size if it + !includes the character length as a dimension as well. + !Ideally the actual type would be checked and handled + !differently, but for now just assume a character array + !and check for ndims = rank+1 + integer, parameter :: var_ndims = 3 !Number of expected variable dimensions on NetCDF file + !---------------------- !Check if file is open: if(.not.this%sima_pio_fh%is_file_open) then @@ -1667,8 +1583,8 @@ subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode, start, co return end if - !Get variable type and number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type, ndims=ndims) + !Get variable type on file: + errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type) if(errcode /= PIO_NOERR) then !Extract error message from PIO: call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) @@ -1688,66 +1604,14 @@ subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode, start, co return end if - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - - !NOTE: NetCDF supports both character arrays and string-type - !data depending on the NetCDF version, so the dimensions - !might be one larger than the actual array size if it - !includes the character length as a dimension as well. - !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 - errcode = 0 - if(ndims /= 3) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data. Note that the first dimenstion !is the length of the character array, so need to start @@ -1805,10 +1669,19 @@ subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode, start, co integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID integer :: nc_type !NetCDF variable type - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + + !NOTE: NetCDF supports both character arrays and string-type + !data depending on the NetCDF version, so the dimensions + !might be one larger than the actual array size if it + !includes the character length as a dimension as well. + !Ideally the actual type would be checked and handled + !differently, but for now just assume a character array + !and check for ndims = rank+1 + integer, parameter :: var_ndims = 4 !Number of expected variable dimensions on NetCDF file + !---------------------- + + !Check if file is open: if(.not.this%sima_pio_fh%is_file_open) then @@ -1836,8 +1709,8 @@ subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode, start, co return end if - !Get variable type and number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type, ndims=ndims) + !Get variable type on file: + errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type) if(errcode /= PIO_NOERR) then !Extract error message from PIO: call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) @@ -1857,66 +1730,14 @@ subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode, start, co return end if - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - - !NOTE: NetCDF supports both character arrays and string-type - !data depending on the NetCDF version, so the dimensions - !might be one larger than the actual array size if it - !includes the character length as a dimension as well. - !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 - errcode = 0 - if(ndims /= 4) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data. Note that the first dimenstion !is the length of the character array, so need to start @@ -1974,10 +1795,17 @@ subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode, start, co integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID integer :: nc_type !NetCDF variable type - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + + !NOTE: NetCDF supports both character arrays and string-type + !data depending on the NetCDF version, so the dimensions + !might be one larger than the actual array size if it + !includes the character length as a dimension as well. + !Ideally the actual type would be checked and handled + !differently, but for now just assume a character array + !and check for ndims = rank+1 + integer, parameter :: var_ndims = 5 !Number of expected variable dimensions on NetCDF file + !---------------------- !Check if file is open: if(.not.this%sima_pio_fh%is_file_open) then @@ -2005,8 +1833,8 @@ subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode, start, co return end if - !Get variable type and number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type, ndims=ndims) + !Get variable type on file: + errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type) if(errcode /= PIO_NOERR) then !Extract error message from PIO: call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) @@ -2026,66 +1854,14 @@ subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode, start, co return end if - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - - !NOTE: NetCDF supports both character arrays and string-type - !data depending on the NetCDF version, so the dimensions - !might be one larger than the actual array size if it - !includes the character length as a dimension as well. - !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 - errcode = 0 - if(ndims /= 5) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data. Note that the first dimenstion !is the length of the character array, so need to start @@ -2144,10 +1920,17 @@ subroutine get_netcdf_var_char_5d(this, varname, var, errmsg, errcode, start, co integer :: err_handling !PIO error handling code integer :: var_id !NetCDF variable ID integer :: nc_type !NetCDF variable type - integer :: ndims !Number of variable dimensions on NetCDF file - integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer :: i !loop control variable + + !NOTE: NetCDF supports both character arrays and string-type + !data depending on the NetCDF version, so the dimensions + !might be one larger than the actual array size if it + !includes the character length as a dimension as well. + !Ideally the actual type would be checked and handled + !differently, but for now just assume a character array + !and check for ndims = rank+1 + integer, parameter :: var_ndims = 6 !Number of expected variable dimensions + !---------------------- !Check if file is open: if(.not.this%sima_pio_fh%is_file_open) then @@ -2175,8 +1958,8 @@ subroutine get_netcdf_var_char_5d(this, varname, var, errmsg, errcode, start, co return end if - !Get variable type and number of variable dimensions on file: - errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type, ndims=ndims) + !Get variable type on file: + errcode = pio_inquire_variable(pio_file_handle, var_id, xtype=nc_type) if(errcode /= PIO_NOERR) then !Extract error message from PIO: call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) @@ -2196,66 +1979,14 @@ subroutine get_netcdf_var_char_5d(this, varname, var, errmsg, errcode, start, co return end if - !Check that the variable rank as specified by the caller - !matches what is found on the NetCDF file: - - !NOTE: NetCDF supports both character arrays and string-type - !data depending on the NetCDF version, so the dimensions - !might be one larger than the actual array size if it - !includes the character length as a dimension as well. - !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 - errcode = 0 - if(ndims /= 6) then - errcode = bad_var_rank_err - errmsg = "Variable '"//trim(varname)//"' isn't declared with the correct number of dimensions" - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - !Get variable dimension sizes: - !Allocate NetCDF variable dimension ID array: - allocate(dim_ids(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Get variable dimension IDs: - errcode = pio_inquire_variable(pio_file_handle, var_id, dimids=dim_ids) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_var_info_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - - !Allocate NetCDF variable dimension sizes array: - allocate(dim_sizes(ndims), stat=errcode, errmsg=errmsg) - if(errcode /= 0) then + call get_dim_sizes(varname, var_ndims, var_id, pio_file_handle, dim_sizes, errcode, errmsg) + if (errcode /= 0) then !Reset PIO back to original error handling method: call pio_seterrorhandling(pio_file_handle, err_handling) return end if - !Get dimension sizes: - do i = 1, ndims - errcode = pio_inq_dimlen(pio_file_handle, dim_ids(i), dim_sizes(i)) - if(errcode /= PIO_NOERR) then - !Extract error message from PIO: - call get_pio_errmsg(pio_inq_dim_len_err, varname, errcode, errmsg) - - !Reset PIO back to original error handling method: - call pio_seterrorhandling(pio_file_handle, err_handling) - return - end if - end do - !Now attempt to allocate and initialize variable, and !read-in the NetCDF data. Note that the first dimenstion !is the length of the character array, so need to start From 73565104ca29ccada1b3ca29f421e629d73a9503 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Fri, 25 Jul 2025 09:30:14 -0600 Subject: [PATCH 06/12] Update the reader object to be constructed as a pointer, not an allocatable. --- .gitmodules | 2 +- src/physics/ncar_ccpp | 2 +- src/physics/utils/pio_reader.F90 | 6 +- .../fortran/src/pio_reader/test_pio_reader.pf | 113 +++++++++++------- 4 files changed, 73 insertions(+), 50 deletions(-) diff --git a/.gitmodules b/.gitmodules index 95fde3bf..3846ce90 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = 6960ce2f8fe0cc45aaf8188f07449028129d5531 + fxtag = 0aba4349625d53604fd7f1230d01f39821464169 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] diff --git a/src/physics/ncar_ccpp b/src/physics/ncar_ccpp index 6960ce2f..0aba4349 160000 --- a/src/physics/ncar_ccpp +++ b/src/physics/ncar_ccpp @@ -1 +1 @@ -Subproject commit 6960ce2f8fe0cc45aaf8188f07449028129d5531 +Subproject commit 0aba4349625d53604fd7f1230d01f39821464169 diff --git a/src/physics/utils/pio_reader.F90 b/src/physics/utils/pio_reader.F90 index 3bd86cef..f3e19730 100644 --- a/src/physics/utils/pio_reader.F90 +++ b/src/physics/utils/pio_reader.F90 @@ -1550,7 +1550,7 @@ subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode, start, co !NOTE: NetCDF supports both character arrays and string-type !data depending on the NetCDF version, so the dimensions !might be one larger than the actual array size if it - !includes the character length as a dimension as well. + !includes the character length as a dimension as well. !Ideally the actual type would be checked and handled !differently, but for now just assume a character array !and check for ndims = rank+1 @@ -1672,7 +1672,7 @@ subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode, start, co integer, allocatable :: dim_sizes(:) !Variable dimension sizes !NOTE: NetCDF supports both character arrays and string-type - !data depending on the NetCDF version, so the dimensions + !data depending on the NetCDF version, so the dimensions !might be one larger than the actual array size if it !includes the character length as a dimension as well. !Ideally the actual type would be checked and handled @@ -1798,7 +1798,7 @@ subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode, start, co integer, allocatable :: dim_sizes(:) !Variable dimension sizes !NOTE: NetCDF supports both character arrays and string-type - !data depending on the NetCDF version, so the dimensions + !data depending on the NetCDF version, so the dimensions !might be one larger than the actual array size if it !includes the character length as a dimension as well. !Ideally the actual type would be checked and handled diff --git a/test/unit/fortran/src/pio_reader/test_pio_reader.pf b/test/unit/fortran/src/pio_reader/test_pio_reader.pf index b10a7f7e..a99ac130 100644 --- a/test/unit/fortran/src/pio_reader/test_pio_reader.pf +++ b/test/unit/fortran/src/pio_reader/test_pio_reader.pf @@ -32,7 +32,7 @@ subroutine test_pio_reader_open_close_file() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -44,7 +44,7 @@ subroutine test_pio_reader_open_close_file() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Check that reader was allocated successfully: @assertTrue(allocated(reader)) @@ -72,6 +72,7 @@ subroutine test_pio_reader_open_close_file() ! Deallocate reader object: deallocate(reader) + nullify(reader) end subroutine test_pio_reader_open_close_file @@ -87,7 +88,7 @@ subroutine test_pio_reader_already_opened_file_err() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -103,7 +104,7 @@ subroutine test_pio_reader_already_opened_file_err() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Attempt to open file: call reader%open_file(fname, errmsg, errcode) @@ -118,6 +119,7 @@ subroutine test_pio_reader_already_opened_file_err() ! Perform test cleanup: call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_already_opened_file_err @@ -135,7 +137,7 @@ subroutine test_pio_reader_no_file_err() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -151,7 +153,7 @@ subroutine test_pio_reader_no_file_err() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Attempt to open non-existent file: call reader%open_file(fname, errmsg, errcode) @@ -162,6 +164,7 @@ subroutine test_pio_reader_no_file_err() ! Perform test cleanup: deallocate(reader) + nullify(reader) end subroutine test_pio_reader_no_file_err @@ -179,7 +182,7 @@ subroutine test_pio_reader_1d_int_read() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -195,7 +198,7 @@ subroutine test_pio_reader_1d_int_read() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -219,6 +222,7 @@ subroutine test_pio_reader_1d_int_read() deallocate(pressure) call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_1d_int_read @@ -234,7 +238,7 @@ subroutine test_pio_reader_2d_int_read() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -249,7 +253,7 @@ subroutine test_pio_reader_2d_int_read() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -274,6 +278,7 @@ subroutine test_pio_reader_2d_int_read() deallocate(minor_limits_gpt_lower) call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_2d_int_read !---------------------------------------- @@ -288,7 +293,7 @@ subroutine test_pio_reader_3d_int_read() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -303,7 +308,7 @@ subroutine test_pio_reader_3d_int_read() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -330,6 +335,7 @@ subroutine test_pio_reader_3d_int_read() deallocate(key_species) call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_3d_int_read @@ -345,7 +351,7 @@ subroutine test_pio_reader_1d_char_read() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -360,7 +366,7 @@ subroutine test_pio_reader_1d_char_read() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -402,6 +408,7 @@ subroutine test_pio_reader_1d_char_read() deallocate(gas_names) call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_1d_char_read @@ -419,7 +426,7 @@ subroutine test_pio_reader_0d_real_read() use ccpp_kinds, only: kind_phys - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -437,7 +444,7 @@ subroutine test_pio_reader_0d_real_read() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -459,6 +466,7 @@ subroutine test_pio_reader_0d_real_read() deallocate(press_ref_trop) call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_0d_real_read @@ -476,7 +484,7 @@ subroutine test_pio_reader_1d_real_read() use ccpp_kinds, only: kind_phys - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -494,7 +502,7 @@ subroutine test_pio_reader_1d_real_read() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -517,6 +525,7 @@ subroutine test_pio_reader_1d_real_read() deallocate(press_ref) call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_1d_real_read @@ -534,7 +543,7 @@ subroutine test_pio_reader_2d_real_read() use ccpp_kinds, only: kind_phys - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -553,7 +562,7 @@ subroutine test_pio_reader_2d_real_read() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -579,6 +588,7 @@ subroutine test_pio_reader_2d_real_read() deallocate(bnd_limits_wavenumber) call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_2d_real_read !---------------------------------------- @@ -595,7 +605,7 @@ subroutine test_pio_reader_3d_real_read() use ccpp_kinds, only: kind_phys - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -613,10 +623,9 @@ subroutine test_pio_reader_3d_real_read() real(kind_phys), parameter :: vmr_ref_absb = 1.99036093_kind_phys real(kind_phys), parameter :: vmr_ref_alay = 14._kind_phys - ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -644,6 +653,7 @@ subroutine test_pio_reader_3d_real_read() deallocate(vmr_ref) call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_3d_real_read @@ -665,7 +675,7 @@ subroutine test_pio_reader_4d_real_read_with_dims() use ccpp_kinds, only: kind_phys - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -695,7 +705,7 @@ subroutine test_pio_reader_4d_real_read_with_dims() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -746,6 +756,7 @@ subroutine test_pio_reader_4d_real_read_with_dims() deallocate(kmajor) call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_4d_real_read_with_dims @@ -769,7 +780,7 @@ subroutine test_pio_reader_int_get_var_file_not_opened_err() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -783,7 +794,7 @@ subroutine test_pio_reader_int_get_var_file_not_opened_err() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Attempt to read variable without opening file: call reader%get_var("pressure", pressure, errmsg, errcode) @@ -794,6 +805,7 @@ subroutine test_pio_reader_int_get_var_file_not_opened_err() ! Perform test cleanup: deallocate(reader) + nullify(reader) end subroutine test_pio_reader_int_get_var_file_not_opened_err @@ -810,7 +822,7 @@ subroutine test_pio_reader_char_get_var_file_not_opened_err() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -824,7 +836,7 @@ subroutine test_pio_reader_char_get_var_file_not_opened_err() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Attempt to read variable without opening file: call reader%get_var("gas_names", gas_names, errmsg, errcode) @@ -835,6 +847,8 @@ subroutine test_pio_reader_char_get_var_file_not_opened_err() ! Perform test cleanup: deallocate(reader) + nullify(reader) + end subroutine test_pio_reader_char_get_var_file_not_opened_err !---------------------------------------- @@ -852,7 +866,7 @@ subroutine test_pio_reader_real_get_var_file_not_opened_err() use ccpp_kinds, only: kind_phys - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -866,7 +880,7 @@ subroutine test_pio_reader_real_get_var_file_not_opened_err() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Attempt to read variable without opening file: call reader%get_var("press_ref", press_ref, errmsg, errcode) @@ -877,6 +891,8 @@ subroutine test_pio_reader_real_get_var_file_not_opened_err() ! Perform test cleanup: deallocate(reader) + nullify(reader) + end subroutine test_pio_reader_real_get_var_file_not_opened_err !---------------------------------------- @@ -896,7 +912,7 @@ subroutine test_pio_reader_get_var_open_close_err() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -913,7 +929,7 @@ subroutine test_pio_reader_get_var_open_close_err() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -930,6 +946,7 @@ subroutine test_pio_reader_get_var_open_close_err() ! Perform test cleanup: deallocate(reader) + nullify(reader) end subroutine test_pio_reader_get_var_open_close_err @@ -945,7 +962,7 @@ subroutine test_pio_reader_int_get_var_missing_var() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -962,7 +979,7 @@ subroutine test_pio_reader_int_get_var_missing_var() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -977,6 +994,7 @@ subroutine test_pio_reader_int_get_var_missing_var() ! Perform test cleanup: call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_int_get_var_missing_var @@ -993,7 +1011,7 @@ subroutine test_pio_reader_char_get_var_missing_var() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -1010,7 +1028,7 @@ subroutine test_pio_reader_char_get_var_missing_var() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -1025,6 +1043,7 @@ subroutine test_pio_reader_char_get_var_missing_var() ! Perform test cleanup: call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_char_get_var_missing_var @@ -1043,7 +1062,7 @@ subroutine test_pio_reader_real_get_var_missing_var() use ccpp_kinds, only: kind_phys - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -1060,7 +1079,7 @@ subroutine test_pio_reader_real_get_var_missing_var() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -1075,6 +1094,7 @@ subroutine test_pio_reader_real_get_var_missing_var() ! Perform test cleanup: call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_real_get_var_missing_var @@ -1091,7 +1111,7 @@ subroutine test_pio_reader_int_get_var_bad_rank() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -1108,7 +1128,7 @@ subroutine test_pio_reader_int_get_var_bad_rank() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -1123,6 +1143,7 @@ subroutine test_pio_reader_int_get_var_bad_rank() ! Perform test cleanup: call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_int_get_var_bad_rank @@ -1139,7 +1160,7 @@ subroutine test_pio_reader_char_get_var_bad_rank() use ccpp_io_reader, only: abstract_netcdf_reader_t use ccpp_io_reader, only: create_netcdf_reader_t - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -1156,7 +1177,7 @@ subroutine test_pio_reader_char_get_var_bad_rank() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -1171,6 +1192,7 @@ subroutine test_pio_reader_char_get_var_bad_rank() ! Perform test cleanup: call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_char_get_var_bad_rank @@ -1189,7 +1211,7 @@ subroutine test_pio_reader_real_get_var_bad_rank() use ccpp_kinds, only: kind_phys - class(abstract_netcdf_reader_t), allocatable :: reader + class(abstract_netcdf_reader_t), pointer :: reader integer :: errcode character(len=256) :: errmsg @@ -1206,7 +1228,7 @@ subroutine test_pio_reader_real_get_var_bad_rank() ! Begin test: - reader = create_netcdf_reader_t() + reader => create_netcdf_reader_t() ! Open file: call reader%open_file(fname, errmsg, errcode) @@ -1221,6 +1243,7 @@ subroutine test_pio_reader_real_get_var_bad_rank() ! Perform test cleanup: call reader%close_file(errmsg, errcode) deallocate(reader) + nullify(reader) end subroutine test_pio_reader_real_get_var_bad_rank From 2a29ce445097e54acc1bd92c9e88cc968755d7d1 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Fri, 25 Jul 2025 09:40:17 -0600 Subject: [PATCH 07/12] Check for reader association, not allocation. --- test/unit/fortran/src/pio_reader/test_pio_reader.pf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/fortran/src/pio_reader/test_pio_reader.pf b/test/unit/fortran/src/pio_reader/test_pio_reader.pf index a99ac130..4b255d82 100644 --- a/test/unit/fortran/src/pio_reader/test_pio_reader.pf +++ b/test/unit/fortran/src/pio_reader/test_pio_reader.pf @@ -47,7 +47,7 @@ subroutine test_pio_reader_open_close_file() reader => create_netcdf_reader_t() ! Check that reader was allocated successfully: - @assertTrue(allocated(reader)) + @assertAssociated(reader) ! Attempt to open file: call reader%open_file(fname, errmsg, errcode) @@ -638,7 +638,7 @@ subroutine test_pio_reader_3d_real_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assertTrue(allocated(vmr_ref)) + @assert(allocated(vmr_ref)) @assertEqual(2, size(vmr_ref, dim=1)) @assertEqual(20, size(vmr_ref, dim=2)) @assertEqual(14, size(vmr_ref, dim=3)) From 0afb2230a70257c02b117a6618ee3ec0f24782fc Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Fri, 25 Jul 2025 09:48:28 -0600 Subject: [PATCH 08/12] Fix syntax error. --- test/unit/fortran/src/pio_reader/test_pio_reader.pf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/fortran/src/pio_reader/test_pio_reader.pf b/test/unit/fortran/src/pio_reader/test_pio_reader.pf index 4b255d82..feaac718 100644 --- a/test/unit/fortran/src/pio_reader/test_pio_reader.pf +++ b/test/unit/fortran/src/pio_reader/test_pio_reader.pf @@ -638,7 +638,7 @@ subroutine test_pio_reader_3d_real_read() @assertEqual('', errmsg) ! Check that the variable's properties are correct: - @assert(allocated(vmr_ref)) + @assertTrue(allocated(vmr_ref)) @assertEqual(2, size(vmr_ref, dim=1)) @assertEqual(20, size(vmr_ref, dim=2)) @assertEqual(14, size(vmr_ref, dim=3)) From 63748eca048efc96d4e84f6a74c818398e6c36b5 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Fri, 25 Jul 2025 15:41:48 -0600 Subject: [PATCH 09/12] Remove branch from github workflow file. --- .github/workflows/fortran_unit_tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/fortran_unit_tests.yml b/.github/workflows/fortran_unit_tests.yml index 5a274225..c2143ac7 100644 --- a/.github/workflows/fortran_unit_tests.yml +++ b/.github/workflows/fortran_unit_tests.yml @@ -5,7 +5,6 @@ on: branches: - development - main - - pio_reader_updates pull_request: workflow_dispatch: From 46dc27dbfd3ff675ed436e809df78fd4020b8099 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Thu, 31 Jul 2025 10:41:33 -0600 Subject: [PATCH 10/12] Update comments as requested during code review. --- src/physics/utils/pio_reader.F90 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/physics/utils/pio_reader.F90 b/src/physics/utils/pio_reader.F90 index f3e19730..bd55065a 100644 --- a/src/physics/utils/pio_reader.F90 +++ b/src/physics/utils/pio_reader.F90 @@ -260,7 +260,7 @@ subroutine get_netcdf_var_int_1d(this, varname, var, errmsg, errcode, start, cou integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 1 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 1 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -352,7 +352,7 @@ subroutine get_netcdf_var_int_2d(this, varname, var, errmsg, errcode, start, cou integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 2 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 2 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -444,7 +444,7 @@ subroutine get_netcdf_var_int_3d(this, varname, var, errmsg, errcode, start, cou integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 3 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 3 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -538,7 +538,7 @@ subroutine get_netcdf_var_int_4d(this, varname, var, errmsg, errcode, start, cou integer, allocatable :: dim_ids(:) !Variable dimension IDs integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 4 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 4 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -630,7 +630,7 @@ subroutine get_netcdf_var_int_5d(this, varname, var, errmsg, errcode, start, cou integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 5 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 5 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -832,7 +832,7 @@ subroutine get_netcdf_var_real_1d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 1 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 1 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -924,7 +924,7 @@ subroutine get_netcdf_var_real_2d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 2 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 2 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -1016,7 +1016,7 @@ subroutine get_netcdf_var_real_3d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 3 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 3 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -1108,7 +1108,7 @@ subroutine get_netcdf_var_real_4d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 4 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 4 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -1200,7 +1200,7 @@ subroutine get_netcdf_var_real_5d(this, varname, var, errmsg, errcode, start, co integer :: var_id !NetCDF variable ID integer, allocatable :: dim_sizes(:) !Variable dimension sizes - integer, parameter :: var_ndims = 5 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 5 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -1306,7 +1306,7 @@ subroutine get_netcdf_var_char_0d(this, varname, var, errmsg, errcode, start, co !Ideally the actual type would be checked and handled !differently, but for now just assume a character array !and check for ndims = rank+1 - integer, parameter :: var_ndims = 1 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 1 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -1430,7 +1430,7 @@ subroutine get_netcdf_var_char_1d(this, varname, var, errmsg, errcode, start, co !Ideally the actual type would be checked and handled !differently, but for now just assume a character array !and check for ndims = rank+1 - integer, parameter :: var_ndims = 2 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 2 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -1554,7 +1554,7 @@ subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode, start, co !Ideally the actual type would be checked and handled !differently, but for now just assume a character array !and check for ndims = rank+1 - integer, parameter :: var_ndims = 3 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 3 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -1678,7 +1678,7 @@ subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode, start, co !Ideally the actual type would be checked and handled !differently, but for now just assume a character array !and check for ndims = rank+1 - integer, parameter :: var_ndims = 4 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 4 !Number of expected dimensions for variable in NetCDF file !---------------------- @@ -1804,7 +1804,7 @@ subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode, start, co !Ideally the actual type would be checked and handled !differently, but for now just assume a character array !and check for ndims = rank+1 - integer, parameter :: var_ndims = 5 !Number of expected variable dimensions on NetCDF file + integer, parameter :: var_ndims = 5 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: @@ -1929,7 +1929,7 @@ subroutine get_netcdf_var_char_5d(this, varname, var, errmsg, errcode, start, co !Ideally the actual type would be checked and handled !differently, but for now just assume a character array !and check for ndims = rank+1 - integer, parameter :: var_ndims = 6 !Number of expected variable dimensions + integer, parameter :: var_ndims = 6 !Number of expected dimensions for variable in NetCDF file !---------------------- !Check if file is open: From e07134d6ca29fbdd8d1c689553ea77074a9a5f34 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Thu, 31 Jul 2025 10:42:00 -0600 Subject: [PATCH 11/12] Update submodule to point to official atmospheric_physics repo. --- .gitmodules | 4 ++-- src/physics/ncar_ccpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 3846ce90..4a4476a4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,8 +19,8 @@ fxDONOTUSEurl = https://github.com/MPAS-Dev/MPAS-Model.git [submodule "ncar-physics"] path = src/physics/ncar_ccpp - url = https://github.com/nusbaume/atmospheric_physics - fxtag = 0aba4349625d53604fd7f1230d01f39821464169 + url = https://github.com/ESCOMP/atmospheric_physics + fxtag = 178c1833d72a4027c6162a6c11b52bbbdcb272b6 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] diff --git a/src/physics/ncar_ccpp b/src/physics/ncar_ccpp index 0aba4349..178c1833 160000 --- a/src/physics/ncar_ccpp +++ b/src/physics/ncar_ccpp @@ -1 +1 @@ -Subproject commit 0aba4349625d53604fd7f1230d01f39821464169 +Subproject commit 178c1833d72a4027c6162a6c11b52bbbdcb272b6 From 4ce8d93607b03ce6bdf5fc487fe28bf2e7b52a62 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Thu, 31 Jul 2025 11:31:43 -0600 Subject: [PATCH 12/12] Update character array comments as requested during code review. --- src/physics/utils/pio_reader.F90 | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/physics/utils/pio_reader.F90 b/src/physics/utils/pio_reader.F90 index bd55065a..3868e8c3 100644 --- a/src/physics/utils/pio_reader.F90 +++ b/src/physics/utils/pio_reader.F90 @@ -1304,8 +1304,8 @@ subroutine get_netcdf_var_char_0d(this, varname, var, errmsg, errcode, start, co !might be one larger than the actual array size if it !includes the character length as a dimension as well. !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 + !differently, but for now just confirm it's a character + !array and check for ndims = rank+1 integer, parameter :: var_ndims = 1 !Number of expected dimensions for variable in NetCDF file !---------------------- @@ -1428,8 +1428,8 @@ subroutine get_netcdf_var_char_1d(this, varname, var, errmsg, errcode, start, co !might be one larger than the actual array size if it !includes the character length as a dimension as well. !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 + !differently, but for now just confirm it's a character + !array and check for ndims = rank+1 integer, parameter :: var_ndims = 2 !Number of expected dimensions for variable in NetCDF file !---------------------- @@ -1552,8 +1552,8 @@ subroutine get_netcdf_var_char_2d(this, varname, var, errmsg, errcode, start, co !might be one larger than the actual array size if it !includes the character length as a dimension as well. !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 + !differently, but for now just confirm it's a character + !array and check for ndims = rank+1 integer, parameter :: var_ndims = 3 !Number of expected dimensions for variable in NetCDF file !---------------------- @@ -1676,8 +1676,8 @@ subroutine get_netcdf_var_char_3d(this, varname, var, errmsg, errcode, start, co !might be one larger than the actual array size if it !includes the character length as a dimension as well. !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 + !differently, but for now just confirm it's a character + !array and check for ndims = rank+1 integer, parameter :: var_ndims = 4 !Number of expected dimensions for variable in NetCDF file !---------------------- @@ -1802,8 +1802,8 @@ subroutine get_netcdf_var_char_4d(this, varname, var, errmsg, errcode, start, co !might be one larger than the actual array size if it !includes the character length as a dimension as well. !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 + !differently, but for now just confirm it's a character + !array and check for ndims = rank+1 integer, parameter :: var_ndims = 5 !Number of expected dimensions for variable in NetCDF file !---------------------- @@ -1927,8 +1927,8 @@ subroutine get_netcdf_var_char_5d(this, varname, var, errmsg, errcode, start, co !might be one larger than the actual array size if it !includes the character length as a dimension as well. !Ideally the actual type would be checked and handled - !differently, but for now just assume a character array - !and check for ndims = rank+1 + !differently, but for now just confirm it's a character + !array and check for ndims = rank+1 integer, parameter :: var_ndims = 6 !Number of expected dimensions for variable in NetCDF file !----------------------