diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 92ef52a5d..fc2e00775 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -25,5 +25,5 @@ | Pierre-siddall | Pierre Siddall | Met Office | 2026-01-29 | | mo-lucy-gordon | Lucy Gordon | Met Office | 2026-03-18 | | shreybh1 | Shrey Bhardwaj | Met Office | 2026-03-26 | - +| allynt | Allyn Treshansky | Met Office | 2026-04-20 | diff --git a/components/lfric-xios/source/lfric_xios_read_mod.F90 b/components/lfric-xios/source/lfric_xios_read_mod.F90 index 456ce5f3d..a91daa862 100644 --- a/components/lfric-xios/source/lfric_xios_read_mod.F90 +++ b/components/lfric-xios/source/lfric_xios_read_mod.F90 @@ -119,7 +119,7 @@ subroutine checkpoint_read_value(io_value, value_name) class(io_value_type), intent(inout) :: io_value character(*), optional, intent(in) :: value_name character(str_def) :: restart_id - integer(i_def) :: array_dims + real(kind=r_def), allocatable :: data_value(:) integer(tik) :: timing_id if ( LPROF ) call start_timing(timing_id, 'lfric_xios.chkpt_readv') @@ -129,11 +129,11 @@ subroutine checkpoint_read_value(io_value, value_name) else restart_id = "restart_" // trim(io_value%io_id) end if - array_dims = size(io_value%data) if ( xios_is_valid_field(trim(restart_id)) ) then - call xios_recv_field( trim(restart_id), & - io_value%data(1:array_dims) ) + allocate(data_value, source=io_value%get_data()) + call xios_recv_field( trim(restart_id), data_value ) + call io_value%set_data(data_value) else call log_event( 'No XIOS field with id="'//trim(restart_id)//'" is defined', & LOG_LEVEL_ERROR ) diff --git a/components/lfric-xios/source/lfric_xios_write_mod.F90 b/components/lfric-xios/source/lfric_xios_write_mod.F90 index 634aefd1b..67b65855d 100644 --- a/components/lfric-xios/source/lfric_xios_write_mod.F90 +++ b/components/lfric-xios/source/lfric_xios_write_mod.F90 @@ -83,8 +83,8 @@ subroutine write_value_generic(io_value, value_name) class(io_value_type), intent(inout) :: io_value character(*), optional, intent(in) :: value_name - integer(i_def) :: array_dims character(:), allocatable :: value_id + real(kind=r_def), allocatable :: data_value(:) if (present(value_name)) then value_id = value_name @@ -92,10 +92,10 @@ subroutine write_value_generic(io_value, value_name) value_id = io_value%io_id end if - array_dims = size(io_value%data) if ( xios_is_valid_field(trim(value_id)) ) then + allocate(data_value, source=io_value%get_data()) call xios_send_field( trim(value_id), & - reshape(io_value%data, (/ 1, array_dims /)) ) + reshape(data_value, (/ 1, size(data_value) /)) ) else call log_event( 'No XIOS field with id="'//trim(io_value%io_id)//'" is defined', & LOG_LEVEL_ERROR ) @@ -191,17 +191,18 @@ subroutine checkpoint_write_value(io_value, value_name) character(*), optional, intent(in) :: value_name character(str_def) :: checkpoint_id - integer(i_def) :: array_dims + real(kind=r_def), allocatable :: data_value(:) if(present(value_name)) then checkpoint_id = trim(value_name) else checkpoint_id = trim(io_value%io_id) end if - array_dims = size(io_value%data) + if ( xios_is_valid_field(trim(checkpoint_id)) ) then + allocate(data_value, source=io_value%get_data()) call xios_send_field( trim(checkpoint_id), & - reshape(io_value%data, (/ 1, array_dims /)) ) + reshape(data_value, (/ 1, size(data_value) /)) ) else call log_event( 'No XIOS field with id="'//trim(checkpoint_id)//'" is defined', & LOG_LEVEL_ERROR ) diff --git a/infrastructure/source/io/io_value_mod.f90 b/infrastructure/source/io/io_value_mod.f90 index d9c0562b9..47290171a 100644 --- a/infrastructure/source/io/io_value_mod.f90 +++ b/infrastructure/source/io/io_value_mod.f90 @@ -6,7 +6,7 @@ module io_value_mod - use constants_mod, only : str_def, r_def, r_double, l_def + use constants_mod, only : str_def, r_def, r_double, l_def, i_def use key_value_mod, only : abstract_value_type use key_value_collection_mod, only : key_value_collection_type use log_mod, only : log_event, & @@ -22,12 +22,15 @@ module io_value_mod !> that can be stored in a key-value pair type, extends(abstract_value_type) :: io_value_type character(str_def) :: io_id - real(kind=r_def), allocatable :: data(:) + real(kind=r_def), private, allocatable :: data(:) procedure(io_operation_interface), pointer :: write_method => null() procedure(io_operation_interface), pointer :: checkpoint_read_method => null() procedure(io_operation_interface), pointer :: checkpoint_write_method => null() contains procedure, public :: init + procedure, public :: set_data + procedure, public :: get_data + procedure, public :: get_data_size procedure, public :: set_write_behaviour procedure, public :: set_checkpoint_write_behaviour procedure, public :: set_checkpoint_read_behaviour @@ -49,18 +52,53 @@ end subroutine io_operation_interface !> @brief Initialiser for the io_value_type !> @param[in] io_id The ID used for managing I/O operations -!> @param[in] data An array holding the data -subroutine init(self, io_id, data) +!> @param[in] data_value An array holding the data +subroutine init(self, io_id, data_value) class(io_value_type), intent(inout) :: self character(len=*), intent(in) :: io_id - real(kind=r_def), intent(in) :: data(:) + real(kind=r_def), intent(in) :: data_value(:) self%io_id = io_id - allocate(self%data, source=data) + allocate(self%data, source=data_value) end subroutine init +!> @brief Sets the data attribute for io_value +!> @param[in] data_value An array holding the data +subroutine set_data(self, data_value) + class(io_value_type), intent(inout) :: self + real(kind=r_def), intent(in) :: data_value(:) + + if ( allocated(self%data) ) then + deallocate(self%data) + end if + allocate(self%data, source=data_value) + +end subroutine set_data + +!> @brief Gets the data from io_value +!> @return array holding the data +function get_data(self) result(data_value) + class(io_value_type), intent(in) :: self + + real(kind=r_def), dimension(1:size(self%data)) :: data_value + + data_value = self%data + +end function get_data + +!> @brief Gets the size of the data from io_value +!> @return integer specifying the size of the data +function get_data_size(self) result(data_size) + class(io_value_type), intent(in) :: self + + integer(i_def) :: data_size + + data_size = size(self%data) + +end function get_data_size + !> @brief Sets the diagnostic write behaviour for io_value !> @param[in] write_behaviour Pointer to procedure implementing the write method subroutine set_write_behaviour(self, write_behaviour)