module m_io_manager !! Provides a high-level manager that orchestrates all checkpoint, !! snapshot, and statistics operations. !! !! @details This module acts as a facade to the I/O subsystem. !! Its purpose is to simplify the main simulation loop by providing !! a single point of contact for all I/O-related actions. The mainprogram only !! needs to interact with the `io_manager_t` type, which then delegates tasks !! to the specialised checkpoint, snapshot, and statistics managers. use mpi, only: MPI_COMM_WORLD use m_checkpoint_manager, only: checkpoint_manager_t use m_checkpoint_state, only: checkpoint_state_t use m_snapshot_manager, only: snapshot_manager_t use m_stats, only: stats_manager_t use m_solver, only: solver_t implicit none private public :: io_manager_t type :: io_manager_t type(checkpoint_manager_t) :: checkpoint_mgr type(snapshot_manager_t) :: snapshot_mgr type(stats_manager_t) :: stats_mgr class(checkpoint_state_t), pointer :: additional_checkpoint_state => null() contains procedure :: init => io_init procedure :: handle_restart => io_handle_restart procedure :: handle_io_step => io_handle_step procedure :: update_stats => io_update_stats procedure :: register_checkpoint_state procedure :: unregister_checkpoint_state procedure :: finalise => io_finalise procedure :: is_restart => io_is_restart end type io_manager_t contains subroutine io_init(self, solver, comm) class(io_manager_t), intent(inout) :: self class(solver_t), intent(in) :: solver integer, intent(in) :: comm call self%checkpoint_mgr%init(comm) call self%snapshot_mgr%init(comm) call self%stats_mgr%init(solver, comm) end subroutine io_init subroutine io_handle_restart(self, solver, comm) class(io_manager_t), intent(inout) :: self class(solver_t), intent(inout) :: solver integer, intent(in), optional :: comm call self%checkpoint_mgr%handle_restart(solver, comm, self%stats_mgr) end subroutine io_handle_restart subroutine io_update_stats(self, solver, iter) class(io_manager_t), intent(inout) :: self class(solver_t), intent(in) :: solver integer, intent(in) :: iter call self%stats_mgr%update(solver, iter) end subroutine io_update_stats subroutine register_checkpoint_state(self, checkpoint_state, comm) class(io_manager_t), intent(inout) :: self class(checkpoint_state_t), target, intent(inout) :: checkpoint_state integer, intent(in), optional :: comm integer :: comm_to_use comm_to_use = MPI_COMM_WORLD if (present(comm)) comm_to_use = comm self%additional_checkpoint_state => checkpoint_state call self%checkpoint_mgr%restore_state(checkpoint_state, comm_to_use) end subroutine register_checkpoint_state subroutine unregister_checkpoint_state(self) class(io_manager_t), intent(inout) :: self nullify (self%additional_checkpoint_state) end subroutine unregister_checkpoint_state subroutine io_handle_step(self, solver, timestep, comm) class(io_manager_t), intent(inout) :: self class(solver_t), intent(in) :: solver integer, intent(in) :: timestep integer, intent(in), optional :: comm integer :: comm_to_use comm_to_use = MPI_COMM_WORLD if (present(comm)) comm_to_use = comm if (associated(self%additional_checkpoint_state)) then call self%checkpoint_mgr%handle_checkpoint_step( & solver, timestep, comm_to_use, self%stats_mgr, & self%additional_checkpoint_state & ) else call self%checkpoint_mgr%handle_checkpoint_step( & solver, timestep, comm_to_use, self%stats_mgr & ) end if call self%snapshot_mgr%handle_snapshot_step(solver, timestep, comm_to_use) call self%stats_mgr%write_stats(solver, timestep, comm_to_use) end subroutine io_handle_step function io_is_restart(self) result(is_restart) class(io_manager_t), intent(in) :: self logical :: is_restart is_restart = self%checkpoint_mgr%is_restart() end function io_is_restart subroutine io_finalise(self) class(io_manager_t), intent(inout) :: self call self%checkpoint_mgr%finalise() call self%snapshot_mgr%finalise() call self%stats_mgr%finalise() end subroutine io_finalise end module m_io_manager