dyn_mpas_run Subroutine

private subroutine dyn_mpas_run(self)

Uses

    • mpas_timekeeping
    • mpas_derived_types
    • atm_core
    • mpas_pool_routines
  • proc~~dyn_mpas_run~~UsesGraph proc~dyn_mpas_run mpas_dynamical_core_type%dyn_mpas_run atm_core atm_core proc~dyn_mpas_run->atm_core mpas_derived_types mpas_derived_types proc~dyn_mpas_run->mpas_derived_types mpas_pool_routines mpas_pool_routines proc~dyn_mpas_run->mpas_pool_routines mpas_timekeeping mpas_timekeeping proc~dyn_mpas_run->mpas_timekeeping

This subroutine calls MPAS dynamical solver in a loop, with each iteration of the loop advancing the dynamical states forward by one time step, until the coupling time interval is reached. Essentially, it closely follows what is done in atm_core_run, but without any calls to MPAS diagnostics manager or MPAS stream manager. Ported and refactored for CAM-SIMA. (KCW, 2024-06-21)

Type Bound

mpas_dynamical_core_type

Arguments

Type IntentOptional Attributes Name
class(mpas_dynamical_core_type), intent(inout) :: self

Calls

proc~~dyn_mpas_run~~CallsGraph proc~dyn_mpas_run mpas_dynamical_core_type%dyn_mpas_run atm_compute_output_diagnostics atm_compute_output_diagnostics proc~dyn_mpas_run->atm_compute_output_diagnostics atm_do_timestep atm_do_timestep proc~dyn_mpas_run->atm_do_timestep mpas_advance_clock mpas_advance_clock proc~dyn_mpas_run->mpas_advance_clock mpas_get_clock_time mpas_get_clock_time proc~dyn_mpas_run->mpas_get_clock_time mpas_get_time mpas_get_time proc~dyn_mpas_run->mpas_get_time mpas_pool_shift_time_levels mpas_pool_shift_time_levels proc~dyn_mpas_run->mpas_pool_shift_time_levels mpas_set_timeinterval mpas_set_timeinterval proc~dyn_mpas_run->mpas_set_timeinterval none~get_variable_pointer mpas_dynamical_core_type%get_variable_pointer proc~dyn_mpas_run->none~get_variable_pointer proc~dyn_mpas_debug_print mpas_dynamical_core_type%dyn_mpas_debug_print proc~dyn_mpas_run->proc~dyn_mpas_debug_print proc~dyn_mpas_get_pool_pointer mpas_dynamical_core_type%dyn_mpas_get_pool_pointer proc~dyn_mpas_run->proc~dyn_mpas_get_pool_pointer proc~stringify stringify proc~dyn_mpas_run->proc~stringify proc~dyn_mpas_get_variable_pointer_c0 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_c0 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_c0 proc~dyn_mpas_get_variable_pointer_c1 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_c1 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_c1 proc~dyn_mpas_get_variable_pointer_i0 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_i0 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_i0 proc~dyn_mpas_get_variable_pointer_i1 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_i1 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_i1 proc~dyn_mpas_get_variable_pointer_i2 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_i2 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_i2 proc~dyn_mpas_get_variable_pointer_i3 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_i3 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_i3 proc~dyn_mpas_get_variable_pointer_l0 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_l0 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_l0 proc~dyn_mpas_get_variable_pointer_r0 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_r0 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_r0 proc~dyn_mpas_get_variable_pointer_r1 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_r1 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_r1 proc~dyn_mpas_get_variable_pointer_r2 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_r2 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_r2 proc~dyn_mpas_get_variable_pointer_r3 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_r3 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_r3 proc~dyn_mpas_get_variable_pointer_r4 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_r4 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_r4 proc~dyn_mpas_get_variable_pointer_r5 mpas_dynamical_core_type%dyn_mpas_get_variable_pointer_r5 none~get_variable_pointer->proc~dyn_mpas_get_variable_pointer_r5 proc~dyn_mpas_debug_print->proc~stringify mpas_pool_get_subpool mpas_pool_get_subpool proc~dyn_mpas_get_pool_pointer->mpas_pool_get_subpool proc~dyn_mpas_get_variable_pointer_c0->proc~dyn_mpas_get_pool_pointer mpas_pool_get_array mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_c0->mpas_pool_get_array mpas_pool_get_config mpas_pool_get_config proc~dyn_mpas_get_variable_pointer_c0->mpas_pool_get_config proc~dyn_mpas_get_variable_pointer_c1->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_c1->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_i0->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_i0->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_i0->mpas_pool_get_config mpas_pool_get_dimension mpas_pool_get_dimension proc~dyn_mpas_get_variable_pointer_i0->mpas_pool_get_dimension proc~dyn_mpas_get_variable_pointer_i1->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_i1->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_i1->mpas_pool_get_dimension proc~dyn_mpas_get_variable_pointer_i2->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_i2->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_i3->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_i3->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_l0->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_l0->mpas_pool_get_config proc~dyn_mpas_get_variable_pointer_r0->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r0->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r0->mpas_pool_get_config proc~dyn_mpas_get_variable_pointer_r1->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r1->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r2->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r2->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r3->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r3->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r4->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r4->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r5->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r5->mpas_pool_get_array

Called by

proc~~dyn_mpas_run~~CalledByGraph proc~dyn_mpas_run mpas_dynamical_core_type%dyn_mpas_run proc~dyn_run dyn_run proc~dyn_run->proc~dyn_mpas_run proc~stepon_run3 stepon_run3 proc~stepon_run3->proc~dyn_run

Variables

Type Visibility Attributes Name Initial
real(kind=rkind), private, pointer :: config_dt
character(len=strkind), private :: date_time
integer, private :: ierr
type(mpas_pool_type), private, pointer :: mpas_pool_diag
type(mpas_pool_type), private, pointer :: mpas_pool_mesh
type(mpas_pool_type), private, pointer :: mpas_pool_state
type(mpas_time_type), private :: mpas_time_end
type(mpas_timeinterval_type), private :: mpas_time_interval
type(mpas_time_type), private :: mpas_time_now
character(len=*), private, parameter :: subname = 'dyn_mpas_subdriver::dyn_mpas_run'

Source Code

    subroutine dyn_mpas_run(self)
        ! Module(s) from MPAS.
        use atm_core, only: atm_compute_output_diagnostics, atm_do_timestep
        use mpas_derived_types, only: mpas_pool_type, mpas_time_type, mpas_timeinterval_type, &
                                      mpas_now
        use mpas_pool_routines, only: mpas_pool_shift_time_levels
        use mpas_timekeeping, only: mpas_advance_clock, mpas_get_clock_time, mpas_get_time, &
                                    mpas_set_timeinterval, &
                                    operator(+), operator(<)

        class(mpas_dynamical_core_type), intent(inout) :: self

        character(*), parameter :: subname = 'dyn_mpas_subdriver::dyn_mpas_run'
        character(strkind) :: date_time
        integer :: ierr
        real(rkind), pointer :: config_dt
        type(mpas_pool_type), pointer :: mpas_pool_diag, mpas_pool_mesh, mpas_pool_state
        type(mpas_time_type) :: mpas_time_end, mpas_time_now ! This derived type is analogous to `ESMF_Time`.
        type(mpas_timeinterval_type) :: mpas_time_interval   ! This derived type is analogous to `ESMF_TimeInterval`.

        call self % debug_print(log_level_debug, subname // ' entered')

        nullify(config_dt)
        nullify(mpas_pool_diag, mpas_pool_mesh, mpas_pool_state)

        call self % get_variable_pointer(config_dt, 'cfg', 'config_dt')
        call self % get_pool_pointer(mpas_pool_diag, 'diag')
        call self % get_pool_pointer(mpas_pool_mesh, 'mesh')
        call self % get_pool_pointer(mpas_pool_state, 'state')

        mpas_time_now = mpas_get_clock_time(self % domain_ptr % clock, mpas_now, ierr=ierr)

        if (ierr /= 0) then
            call self % model_error('Failed to get time for "mpas_now"', subname, __LINE__)
        end if

        call mpas_get_time(mpas_time_now, datetimestring=date_time, ierr=ierr)

        if (ierr /= 0) then
            call self % model_error('Failed to get time for "mpas_now"', subname, __LINE__)
        end if

        call self % debug_print(log_level_info, 'Time integration of MPAS dynamical core begins at ' // trim(adjustl(date_time)))

        call mpas_set_timeinterval(mpas_time_interval, s=self % coupling_time_interval, ierr=ierr)

        if (ierr /= 0) then
            call self % model_error('Failed to set coupling time interval', subname, __LINE__)
        end if

        ! The `+` operator is overloaded here.
        mpas_time_end = mpas_time_now + mpas_time_interval

        ! Integrate until the coupling time interval is reached.
        ! The `<` operator is overloaded here.
        do while (mpas_time_now < mpas_time_end)
            ! Number of time steps that has been completed in this MPAS dynamical core instance.
            self % number_of_time_steps = self % number_of_time_steps + 1

            ! Advance the dynamical states forward in time by `config_dt` seconds.
            ! Current states are in time level 1. Upon exit, time level 2 will contain updated states.
            call atm_do_timestep(self % domain_ptr, config_dt, self % number_of_time_steps)

            ! MPAS "state" pool has two time levels.
            ! Swap them after advancing a time step.
            call mpas_pool_shift_time_levels(mpas_pool_state)

            call mpas_advance_clock(self % domain_ptr % clock, ierr=ierr)

            if (ierr /= 0) then
                call self % model_error('Failed to advance clock', subname, __LINE__)
            end if

            mpas_time_now = mpas_get_clock_time(self % domain_ptr % clock, mpas_now, ierr=ierr)

            if (ierr /= 0) then
                call self % model_error('Failed to get time for "mpas_now"', subname, __LINE__)
            end if

            call self % debug_print(log_level_info, 'Time step ' // stringify([self % number_of_time_steps]) // ' completed')
        end do

        call mpas_get_time(mpas_time_now, datetimestring=date_time, ierr=ierr)

        if (ierr /= 0) then
            call self % model_error('Failed to get time for "mpas_now"', subname, __LINE__)
        end if

        call self % debug_print(log_level_info, 'Time integration of MPAS dynamical core ends at ' // trim(adjustl(date_time)))

        ! Compute diagnostic variables like "pressure", "rho", and "theta" from time level 1 of MPAS "state" pool
        ! by calling upstream MPAS functionality.
        call atm_compute_output_diagnostics(mpas_pool_state, 1, mpas_pool_diag, mpas_pool_mesh)

        nullify(config_dt)
        nullify(mpas_pool_diag, mpas_pool_mesh, mpas_pool_state)

        call self % debug_print(log_level_debug, subname // ' completed')
    end subroutine dyn_mpas_run