subroutine dyn_mpas_read_write_stream(self, pio_file, stream_mode, stream_name)
! Module(s) from external libraries.
use pio, only: file_desc_t
! Module(s) from MPAS.
use mpas_derived_types, only: mpas_pool_type, mpas_stream_noerr, mpas_stream_type
use mpas_io_streams, only: mpas_closestream, mpas_readstream, mpas_writestream
use mpas_pool_routines, only: mpas_pool_destroy_pool
use mpas_stream_manager, only: postread_reindex, prewrite_reindex, postwrite_reindex
class(mpas_dynamical_core_type), intent(in) :: self
type(file_desc_t), pointer, intent(in) :: pio_file
character(*), intent(in) :: stream_mode
character(*), intent(in) :: stream_name
character(*), parameter :: subname = 'dyn_mpas_subdriver::dyn_mpas_read_write_stream'
integer :: i, ierr
type(mpas_pool_type), pointer :: mpas_pool
type(mpas_stream_type), pointer :: mpas_stream
type(var_info_type), allocatable :: var_info_list(:)
call self % debug_print(log_level_debug, subname // ' entered')
nullify(mpas_pool)
nullify(mpas_stream)
call self % debug_print(log_level_info, 'Initializing stream "' // trim(adjustl(stream_name)) // '"')
call self % init_stream_with_pool(mpas_pool, mpas_stream, pio_file, stream_mode, stream_name)
if (.not. associated(mpas_pool)) then
call self % model_error('Failed to initialize stream "' // trim(adjustl(stream_name)) // '"', subname, __LINE__)
end if
if (.not. associated(mpas_stream)) then
call self % model_error('Failed to initialize stream "' // trim(adjustl(stream_name)) // '"', subname, __LINE__)
end if
select case (trim(adjustl(stream_mode)))
case ('r', 'read')
call self % debug_print(log_level_info, 'Reading stream "' // trim(adjustl(stream_name)) // '"')
call mpas_readstream(mpas_stream, 1, ierr=ierr)
if (ierr /= mpas_stream_noerr) then
call self % model_error('Failed to read stream "' // trim(adjustl(stream_name)) // '"', subname, __LINE__)
end if
! Exchange halo layers because new data have just been read.
var_info_list = parse_stream_name(stream_name)
do i = 1, size(var_info_list)
call self % exchange_halo(var_info_list(i) % name)
end do
! For any connectivity arrays in this stream, convert global indexes to local indexes.
call postread_reindex(self % domain_ptr % blocklist % allfields, self % domain_ptr % packages, &
mpas_pool, mpas_pool)
case ('w', 'write')
call self % debug_print(log_level_info, 'Writing stream "' // trim(adjustl(stream_name)) // '"')
! WARNING:
! The `{pre,post}write_reindex` subroutines are STATEFUL because they store information inside their module
! (i.e., module variables). They MUST be called in pairs, like below, to prevent undefined behaviors.
! For any connectivity arrays in this stream, temporarily convert local indexes to global indexes.
call prewrite_reindex(self % domain_ptr % blocklist % allfields, self % domain_ptr % packages, &
mpas_pool, mpas_pool)
call mpas_writestream(mpas_stream, 1, ierr=ierr)
if (ierr /= mpas_stream_noerr) then
call self % model_error('Failed to write stream "' // trim(adjustl(stream_name)) // '"', subname, __LINE__)
end if
! For any connectivity arrays in this stream, reset global indexes back to local indexes.
call postwrite_reindex(self % domain_ptr % blocklist % allfields, mpas_pool)
case default
call self % model_error('Unsupported stream mode "' // trim(adjustl(stream_mode)) // '"', subname, __LINE__)
end select
call self % debug_print(log_level_info, 'Closing stream "' // trim(adjustl(stream_name)) // '"')
call mpas_closestream(mpas_stream, ierr=ierr)
if (ierr /= mpas_stream_noerr) then
call self % model_error('Failed to close stream "' // trim(adjustl(stream_name)) // '"', subname, __LINE__)
end if
! Deallocate temporary pointers to avoid memory leaks.
call mpas_pool_destroy_pool(mpas_pool)
nullify(mpas_pool)
deallocate(mpas_stream)
nullify(mpas_stream)
call self % debug_print(log_level_debug, subname // ' completed')
end subroutine dyn_mpas_read_write_stream