From b83a1f612908a48f3e525aaab6edb5b78fec4a79 Mon Sep 17 00:00:00 2001 From: Allyn Treshansky Date: Mon, 20 Apr 2026 12:41:43 +0100 Subject: [PATCH 1/2] Made io_value_type data attribute private --- .../lfric-xios/source/lfric_xios_read_mod.F90 | 8 +-- .../source/lfric_xios_write_mod.F90 | 13 ++--- infrastructure/source/io/io_value_mod.f90 | 50 ++++++++++++++++--- 3 files changed, 55 insertions(+), 16 deletions(-) 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) From 074c905ba63f05821a08595a3360e42f02184a54 Mon Sep 17 00:00:00 2001 From: allynt Date: Mon, 20 Apr 2026 12:48:09 +0100 Subject: [PATCH 2/2] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 330823d6e..a6859972a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -23,4 +23,5 @@ | jcsmeto | James Cunningham-Smith | Met Office | 2026-02-06 | | thomasmelvin | Thomas Melvin | Met Office | 2026-01-15 | | ericaneininger | Erica Neininger | Met Office | 2026-03-02 | -| mo-lucy-gordon | Lucy Gordon | Met Office | 2026-03-18 | \ No newline at end of file +| mo-lucy-gordon | Lucy Gordon | Met Office | 2026-03-18 | +| allynt | Allyn Treshansky | Met Office | 2026-04-20 |