dyn_mpas_define_scalar_field Subroutine

private subroutine dyn_mpas_define_scalar_field(self)

Uses

  • proc~~dyn_mpas_define_scalar_field~~UsesGraph proc~dyn_mpas_define_scalar_field mpas_dynamical_core_type%dyn_mpas_define_scalar_field module~dyn_mpas_procedures dyn_mpas_procedures proc~dyn_mpas_define_scalar_field->module~dyn_mpas_procedures mpas_derived_types mpas_derived_types proc~dyn_mpas_define_scalar_field->mpas_derived_types mpas_pool_routines mpas_pool_routines proc~dyn_mpas_define_scalar_field->mpas_pool_routines

In the context of MPAS, a "field" is a data structure that wraps around a raw array of an intrinsic data type, along with its associated metadata. This subroutine uses the sanitized information gathered in dyn_mpas_define_scalar to actually initialize the scalar field data structure inside MPAS. Note that MPAS uses the term "scalar", but CAM-SIMA calls it "constituent".

Type Bound

mpas_dynamical_core_type

Arguments

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

Calls

proc~~dyn_mpas_define_scalar_field~~CallsGraph proc~dyn_mpas_define_scalar_field mpas_dynamical_core_type%dyn_mpas_define_scalar_field constituentnames constituentnames proc~dyn_mpas_define_scalar_field->constituentnames mpas_pool_add_dimension mpas_pool_add_dimension proc~dyn_mpas_define_scalar_field->mpas_pool_add_dimension mpas_pool_add_field mpas_pool_add_field proc~dyn_mpas_define_scalar_field->mpas_pool_add_field mpas_pool_get_field mpas_pool_get_field proc~dyn_mpas_define_scalar_field->mpas_pool_get_field none~get_variable_pointer mpas_dynamical_core_type%get_variable_pointer proc~dyn_mpas_define_scalar_field->none~get_variable_pointer proc~dyn_mpas_debug_print mpas_dynamical_core_type%dyn_mpas_debug_print proc~dyn_mpas_define_scalar_field->proc~dyn_mpas_debug_print proc~dyn_mpas_get_pool_pointer mpas_dynamical_core_type%dyn_mpas_get_pool_pointer proc~dyn_mpas_define_scalar_field->proc~dyn_mpas_get_pool_pointer proc~stringify stringify proc~dyn_mpas_define_scalar_field->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_define_scalar_field~~CalledByGraph proc~dyn_mpas_define_scalar_field mpas_dynamical_core_type%dyn_mpas_define_scalar_field proc~dyn_mpas_define_scalar mpas_dynamical_core_type%dyn_mpas_define_scalar proc~dyn_mpas_define_scalar->proc~dyn_mpas_define_scalar_field proc~dyn_init dyn_init proc~dyn_init->proc~dyn_mpas_define_scalar interface~dyn_init dyn_init interface~dyn_init->proc~dyn_init

Variables

Type Visibility Attributes Name Initial
character(len=strkind), private :: cerr
type(field3dreal), private, pointer :: field_3d_real
type(field3dreal), private, pointer :: field_3d_real_alias(:)
integer, private :: i
integer, private :: ierr
integer, private, pointer :: index_qc
integer, private, pointer :: index_qv
integer, private, pointer :: index_tke
integer, private, pointer :: index_water_end
integer, private, pointer :: index_water_start
integer, private :: j
type(mpas_pool_type), private, pointer :: mpas_pool
character(len=*), private, parameter :: subname = 'dyn_mpas_subdriver::dyn_mpas_define_scalar_field'
integer, private :: time_level

Source Code

    subroutine dyn_mpas_define_scalar_field(self)
        ! Module(s) from MPAS.
        use dyn_mpas_procedures, only: stringify
        use mpas_derived_types, only: field3dreal, mpas_pool_type
        use mpas_pool_routines, only: mpas_pool_add_dimension, mpas_pool_add_field, mpas_pool_get_field

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

        character(*), parameter :: subname = 'dyn_mpas_subdriver::dyn_mpas_define_scalar_field'
        character(strkind) :: cerr
        integer :: i, j
        integer :: ierr
        integer :: time_level
        integer, pointer :: index_qv, index_qc, index_tke, index_water_start, index_water_end
        type(field3dreal), pointer :: field_3d_real, field_3d_real_alias(:)
        type(mpas_pool_type), pointer :: mpas_pool

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

        nullify(index_qv, index_qc, index_tke, index_water_start, index_water_end)
        nullify(field_3d_real, field_3d_real_alias)
        nullify(mpas_pool)

        call self % get_variable_pointer(index_qv, 'dim', 'index_qv')
        call self % get_variable_pointer(index_qc, 'dim', 'index_qc')
        call self % get_variable_pointer(index_tke, 'dim', 'index_tke')
        call self % get_variable_pointer(index_water_start, 'dim', 'moist_start')
        call self % get_variable_pointer(index_water_end, 'dim', 'moist_end')

        ! Define "scalars" field for MPAS.

        call self % debug_print(log_level_info, 'Defining MPAS scalars')

        call self % get_pool_pointer(mpas_pool, 'state')

        ! Add scalar dimensions to MPAS "state" pool.
        call mpas_pool_add_dimension(mpas_pool, 'index_qv', index_qv)
        call mpas_pool_add_dimension(mpas_pool, 'index_qc', index_qc)
        call mpas_pool_add_dimension(mpas_pool, 'index_tke', index_tke)
        call mpas_pool_add_dimension(mpas_pool, 'moist_start', index_water_start)
        call mpas_pool_add_dimension(mpas_pool, 'moist_end', index_water_end)

        ! MPAS "state" pool has two time levels.
        time_level = 2

        allocate(field_3d_real_alias(time_level), errmsg=cerr, stat=ierr)

        if (ierr /= 0) then
            call self % model_error('Failed to allocate field_3d_real_alias' // new_line('') // &
                'Allocation returned with ' // stringify([ierr]) // ': ' // trim(adjustl(cerr)), &
                subname, __LINE__)
        end if

        do i = 1, time_level
            call mpas_pool_get_field(mpas_pool, 'scalars', field_3d_real, timelevel=i)

            if (.not. associated(field_3d_real)) then
                call self % model_error('Failed to find variable "scalars"', subname, __LINE__)
            end if

            do j = 1, self % number_of_constituents
                field_3d_real % constituentnames(j) = &
                    trim(adjustl(self % constituent_name(self % index_mpas_scalar_to_constituent(j))))

                ! Print information about MPAS scalars. Only do it once.
                if (i == 1) then
                    call self % debug_print(log_level_verbose, 'MPAS scalar index ' // stringify([j]))
                    call self % debug_print(log_level_verbose, '    MPAS scalar name: ' // &
                        trim(field_3d_real % constituentnames(j)))
                    if (self % input_alias(self % index_mpas_scalar_to_constituent(j)) /= '') then
                        call self % debug_print(log_level_verbose, '    Input alias: ' // &
                            trim(self % input_alias(self % index_mpas_scalar_to_constituent(j))))
                    end if
                    call self % debug_print(log_level_verbose, '    Is water species: ' // &
                        stringify([self % is_water_species(self % index_mpas_scalar_to_constituent(j))]))
                    call self % debug_print(log_level_verbose, '    Index mapping from MPAS scalar to constituent: ' // &
                        stringify([j]) // ' -> ' // stringify([self % index_mpas_scalar_to_constituent(j)]))
                end if
            end do

            if (index_tke > 0) then
                field_3d_real % constituentnames(index_tke) = 'tke_for_les'
            end if

            ! Typically in MPAS, each constituent has a single authoritative name. However in CAM-SIMA, constituents may have
            ! aliases for reading input. Construct an extra "scalars_alias" field in MPAS at run-time to support this feature.

            ! Remember that an intrinsic assignment on a derived type works like a "shallow copy"; i.e., pointer components
            ! on the LHS are simply pointer-assigned to the RHS. This is the desired behavior here because we want any
            ! operations on the "scalars_alias" field to be reflected in the "scalars" field, including the underlying data.
            field_3d_real_alias(i) = field_3d_real
            field_3d_real_alias(i) % fieldname = 'scalars_alias'

            allocate(field_3d_real_alias(i) % constituentnames(size(field_3d_real % constituentnames)), errmsg=cerr, stat=ierr)

            if (ierr /= 0) then
                call self % model_error('Failed to allocate field_3d_real_alias % constituentnames' // new_line('') // &
                    'Allocation returned with ' // stringify([ierr]) // ': ' // trim(adjustl(cerr)), &
                    subname, __LINE__)
            end if

            field_3d_real_alias(i) % constituentnames(:) = ''
            field_3d_real_alias(i) % constituentnames(1:size(self % input_alias)) = &
                adjustl(self % input_alias(self % index_mpas_scalar_to_constituent))

            nullify(field_3d_real)
        end do

        ! Inform MPAS about the newly constructed field.
        call self % get_pool_pointer(mpas_pool, 'all')

        call mpas_pool_add_field(mpas_pool, 'scalars_alias', field_3d_real_alias)

        nullify(field_3d_real_alias)
        nullify(mpas_pool)

        ! Define "scalars_tend" field for MPAS.

        call self % debug_print(log_level_info, 'Defining MPAS scalar tendencies')

        call self % get_pool_pointer(mpas_pool, 'tend')

        ! Add scalar dimensions to MPAS "tend" pool.
        call mpas_pool_add_dimension(mpas_pool, 'index_qv', index_qv)
        call mpas_pool_add_dimension(mpas_pool, 'index_qc', index_qc)
        call mpas_pool_add_dimension(mpas_pool, 'index_tke', index_tke)
        call mpas_pool_add_dimension(mpas_pool, 'moist_start', index_water_start)
        call mpas_pool_add_dimension(mpas_pool, 'moist_end', index_water_end)

        ! MPAS "tend" pool only has one time level.
        time_level = 1

        do i = 1, time_level
            call mpas_pool_get_field(mpas_pool, 'scalars_tend', field_3d_real, timelevel=i)

            if (.not. associated(field_3d_real)) then
                call self % model_error('Failed to find variable "scalars_tend"', subname, __LINE__)
            end if

            do j = 1, self % number_of_constituents
                field_3d_real % constituentnames(j) = &
                    'tendency_of_' // trim(adjustl(self % constituent_name(self % index_mpas_scalar_to_constituent(j))))

                ! Print information about MPAS scalar tendencies. Only do it once.
                if (i == 1) then
                    call self % debug_print(log_level_verbose, 'MPAS scalar tendency index ' // stringify([j]))
                    call self % debug_print(log_level_verbose, '    MPAS scalar tendency name: ' // &
                        trim(field_3d_real % constituentnames(j)))
                    call self % debug_print(log_level_verbose, '    Is water species: ' // &
                        stringify([self % is_water_species(self % index_mpas_scalar_to_constituent(j))]))
                    call self % debug_print(log_level_verbose, '    Index mapping from MPAS scalar tendency to constituent: ' // &
                        stringify([j]) // ' -> ' // stringify([self % index_mpas_scalar_to_constituent(j)]))
                end if
            end do

            if (index_tke > 0) then
                field_3d_real % constituentnames(index_tke) = 'tendency_of_tke_for_les'
            end if

            nullify(field_3d_real)
        end do

        nullify(mpas_pool)

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