define_cam_grid Subroutine

private subroutine define_cam_grid()

Uses

  • proc~~define_cam_grid~~UsesGraph proc~define_cam_grid define_cam_grid cam_abortutils cam_abortutils proc~define_cam_grid->cam_abortutils cam_grid_support cam_grid_support proc~define_cam_grid->cam_grid_support cam_logfile cam_logfile proc~define_cam_grid->cam_logfile cam_map_utils cam_map_utils proc~define_cam_grid->cam_map_utils dynconst dynconst proc~define_cam_grid->dynconst module~dyn_comp dyn_comp proc~define_cam_grid->module~dyn_comp module~dyn_mpas_subdriver dyn_mpas_subdriver proc~define_cam_grid->module~dyn_mpas_subdriver shr_kind_mod shr_kind_mod proc~define_cam_grid->shr_kind_mod string_utils string_utils proc~define_cam_grid->string_utils module~dyn_comp->module~dyn_mpas_subdriver iso_fortran_env iso_fortran_env module~dyn_mpas_subdriver->iso_fortran_env mpas_derived_types mpas_derived_types module~dyn_mpas_subdriver->mpas_derived_types mpas_kind_types mpas_kind_types module~dyn_mpas_subdriver->mpas_kind_types mpi mpi module~dyn_mpas_subdriver->mpi

This subroutine defines and registers four variants of dynamics grids in terms of dynamics decomposition. Their names are listed in dyn_grid_name and their corresponding ids can be determined by calling dyn_grid_id. * "mpas_cell": Grid that is centered at MPAS "cell" points. * "cam_cell": Grid that is also centered at MPAS "cell" points but uses standard CAM-SIMA coordinate and dimension names. * "mpas_edge": Grid that is centered at MPAS "edge" points. * "mpas_vertex": Grid that is centered at MPAS "vertex" points. (KCW, 2024-03-28)

Arguments

None

Calls

proc~~define_cam_grid~~CallsGraph proc~define_cam_grid define_cam_grid cam_grid_attribute_register cam_grid_attribute_register proc~define_cam_grid->cam_grid_attribute_register cam_grid_register cam_grid_register proc~define_cam_grid->cam_grid_register check_allocate check_allocate proc~define_cam_grid->check_allocate horiz_coord_create horiz_coord_create proc~define_cam_grid->horiz_coord_create none~get_variable_pointer mpas_dynamical_core_type%get_variable_pointer proc~define_cam_grid->none~get_variable_pointer proc~dyn_debug_print dyn_debug_print proc~define_cam_grid->proc~dyn_debug_print proc~dyn_grid_id dyn_grid_id proc~define_cam_grid->proc~dyn_grid_id stringify stringify proc~define_cam_grid->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_debug_print->stringify 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_pool_pointer mpas_dynamical_core_type%dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_c0->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_c1->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_c1->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_i0->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_i1->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_i2->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_i2->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_i3->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_i3->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_l0->mpas_pool_get_config proc~dyn_mpas_get_variable_pointer_l0->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_r0->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r1->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r1->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r2->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r2->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r3->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r3->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r4->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r4->proc~dyn_mpas_get_pool_pointer proc~dyn_mpas_get_variable_pointer_r5->mpas_pool_get_array proc~dyn_mpas_get_variable_pointer_r5->proc~dyn_mpas_get_pool_pointer mpas_pool_get_subpool mpas_pool_get_subpool proc~dyn_mpas_get_pool_pointer->mpas_pool_get_subpool

Called by

proc~~define_cam_grid~~CalledByGraph proc~define_cam_grid define_cam_grid proc~model_grid_init model_grid_init proc~model_grid_init->proc~define_cam_grid

Variables

Type Visibility Attributes Name Initial
real(kind=kind_dyn_mpas), private, pointer :: areacell(:)
real(kind=kind_r8), private, pointer :: cell_area(:)
real(kind=kind_r8), private, pointer :: cell_weight(:)
integer(kind=kind_imap), private, pointer :: global_grid_index(:)
integer(kind=kind_imap), private, pointer :: global_grid_map(:,:)
integer, private :: i
integer, private :: ierr
integer, private, pointer :: indextocellid(:)
integer, private, pointer :: indextoedgeid(:)
integer, private, pointer :: indextovertexid(:)
type(horiz_coord_t), private, pointer :: lat_coord
real(kind=kind_dyn_mpas), private, pointer :: latcell(:)
real(kind=kind_dyn_mpas), private, pointer :: latedge(:)
real(kind=kind_dyn_mpas), private, pointer :: latvertex(:)
type(horiz_coord_t), private, pointer :: lon_coord
real(kind=kind_dyn_mpas), private, pointer :: loncell(:)
real(kind=kind_dyn_mpas), private, pointer :: lonedge(:)
real(kind=kind_dyn_mpas), private, pointer :: lonvertex(:)
character(len=*), private, parameter :: subname = 'dyn_grid::define_cam_grid'

Source Code

    subroutine define_cam_grid()
        ! Module(s) from CAM-SIMA.
        use cam_abortutils, only: check_allocate
        use cam_grid_support, only: cam_grid_attribute_register, cam_grid_register, &
                                    horiz_coord_create, horiz_coord_t
        use cam_logfile, only: debugout_debug, debugout_verbose
        use cam_map_utils, only: kind_imap => imap
        use dyn_comp, only: dyn_debug_print, mpas_dynamical_core, &
                            ncells_global, nedges_global, nvertices_global, &
                            ncells_solve, nedges_solve, nvertices_solve, &
                            sphere_radius
        use dynconst, only: constant_pi => pi, rad_to_deg
        use string_utils, only: stringify
        ! Module(s) from CESM Share.
        use shr_kind_mod, only: kind_r8 => shr_kind_r8
        ! Module(s) from MPAS.
        use dyn_mpas_subdriver, only: kind_dyn_mpas => mpas_dynamical_core_real_kind

        character(*), parameter :: subname = 'dyn_grid::define_cam_grid'
        integer :: i
        integer :: ierr
        integer, pointer :: indextocellid(:)   ! Global indexes of cell centers.
        integer, pointer :: indextoedgeid(:)   ! Global indexes of edge nodes.
        integer, pointer :: indextovertexid(:) ! Global indexes of vertex nodes.
        real(kind_dyn_mpas), pointer :: areacell(:)  ! Cell areas (m2).
        real(kind_dyn_mpas), pointer :: latcell(:)   ! Cell center latitudes (rad).
        real(kind_dyn_mpas), pointer :: latedge(:)   ! Edge node latitudes (rad).
        real(kind_dyn_mpas), pointer :: latvertex(:) ! Vertex node latitudes (rad).
        real(kind_dyn_mpas), pointer :: loncell(:)   ! Cell center longitudes (rad).
        real(kind_dyn_mpas), pointer :: lonedge(:)   ! Edge node longitudes (rad).
        real(kind_dyn_mpas), pointer :: lonvertex(:) ! Vertex node longitudes (rad).

        ! Global grid indexes. CAN be safely deallocated because its values are copied internally by
        ! `cam_grid_attribute_register` and `horiz_coord_create`.
        ! `kind_imap` is an integer kind of `PIO_OFFSET_KIND`.
        integer(kind_imap), pointer :: global_grid_index(:)
        ! Global grid maps. CANNOT be safely deallocated because `cam_grid_register`
        ! just uses pointers to point at it internally.
        ! `kind_imap` is an integer kind of `PIO_OFFSET_KIND`.
        integer(kind_imap), pointer :: global_grid_map(:, :)
        ! Cell areas (m2). CANNOT be safely deallocated because `cam_grid_attribute_register`
        ! just uses pointers to point at it internally.
        real(kind_r8), pointer :: cell_area(:)
        ! Cell weights normalized to unity. CANNOT be safely deallocated because `cam_grid_attribute_register`
        ! just uses pointers to point at it internally.
        real(kind_r8), pointer :: cell_weight(:)
        ! Latitude coordinates. CANNOT be safely deallocated because `cam_grid_register`
        ! just uses pointers to point at it internally.
        type(horiz_coord_t), pointer :: lat_coord
        ! Longitude coordinates. CANNOT be safely deallocated because `cam_grid_register`
        ! just uses pointers to point at it internally.
        type(horiz_coord_t), pointer :: lon_coord

        call dyn_debug_print(debugout_debug, subname // ' entered')

        nullify(indextocellid, indextoedgeid, indextovertexid)
        nullify(areacell)
        nullify(latcell, loncell)
        nullify(latedge, lonedge)
        nullify(latvertex, lonvertex)

        nullify(global_grid_index, global_grid_map)
        nullify(cell_area, cell_weight)
        nullify(lat_coord, lon_coord)

        ! Construct coordinate and grid objects for cell center grid (i.e., "mpas_cell").
        ! Standard MPAS coordinate and dimension names are used.

        call mpas_dynamical_core % get_variable_pointer(areacell, 'mesh', 'areaCell')
        call mpas_dynamical_core % get_variable_pointer(indextocellid, 'mesh', 'indexToCellID')
        call mpas_dynamical_core % get_variable_pointer(latcell, 'mesh', 'latCell')
        call mpas_dynamical_core % get_variable_pointer(loncell, 'mesh', 'lonCell')

        allocate(global_grid_index(ncells_solve), stat=ierr)
        call check_allocate(ierr, subname, 'global_grid_index(ncells_solve)', 'dyn_grid', __LINE__)

        global_grid_index(:) = int(indextocellid(1:ncells_solve), kind_imap)

        lat_coord => horiz_coord_create('latCell', 'nCells', ncells_global, 'latitude', 'degrees_north', &
            1, ncells_solve, real(latcell, kind_r8) * rad_to_deg, map=global_grid_index)
        lon_coord => horiz_coord_create('lonCell', 'nCells', ncells_global, 'longitude', 'degrees_east', &
            1, ncells_solve, real(loncell, kind_r8) * rad_to_deg, map=global_grid_index)

        allocate(cell_area(ncells_solve), stat=ierr)
        call check_allocate(ierr, subname, 'cell_area(ncells_solve)', 'dyn_grid', __LINE__)
        allocate(cell_weight(ncells_solve), stat=ierr)
        call check_allocate(ierr, subname, 'cell_weight(ncells_solve)', 'dyn_grid', __LINE__)
        allocate(global_grid_map(3, ncells_solve), stat=ierr)
        call check_allocate(ierr, subname, 'global_grid_map(3, ncells_solve)', 'dyn_grid', __LINE__)

        do i = 1, ncells_solve
            cell_area(i)   = real(areacell(i), kind_r8)
            cell_weight(i) = real(areacell(i), kind_r8) / (4.0_kind_r8 * constant_pi * real(sphere_radius, kind_r8) ** 2)

            global_grid_map(1, i) = int(i, kind_imap)
            global_grid_map(2, i) = int(1, kind_imap)
            global_grid_map(3, i) = global_grid_index(i)
        end do

        call dyn_debug_print(debugout_verbose, 'Registering dynamics grid "mpas_cell" with id ' // &
            stringify([dyn_grid_id('mpas_cell')]))

        call cam_grid_register('mpas_cell', dyn_grid_id('mpas_cell'), lat_coord, lon_coord, global_grid_map, &
            unstruct=.true., block_indexed=.false.)
        call cam_grid_attribute_register('mpas_cell', 'cell_area', 'MPAS cell area', 'nCells', cell_area, &
            map=global_grid_index)
        call cam_grid_attribute_register('mpas_cell', 'cell_weight', 'MPAS cell weight', 'nCells', cell_weight, &
            map=global_grid_index)

        nullify(areacell)
        nullify(cell_area, cell_weight)
        nullify(lat_coord, lon_coord)

        ! Construct coordinate and grid objects for cell center grid (i.e., "cam_cell").
        ! Standard CAM-SIMA coordinate and dimension names are used.

        lat_coord => horiz_coord_create('lat', 'ncol', ncells_global, 'latitude', 'degrees_north', &
            1, ncells_solve, real(latcell, kind_r8) * rad_to_deg, map=global_grid_index)
        lon_coord => horiz_coord_create('lon', 'ncol', ncells_global, 'longitude', 'degrees_east', &
            1, ncells_solve, real(loncell, kind_r8) * rad_to_deg, map=global_grid_index)

        call dyn_debug_print(debugout_verbose, 'Registering dynamics grid "cam_cell" with id ' // &
            stringify([dyn_grid_id('cam_cell')]))

        call cam_grid_register('cam_cell', dyn_grid_id('cam_cell'), lat_coord, lon_coord, global_grid_map, &
            unstruct=.true., block_indexed=.false.)

        nullify(indextocellid)
        nullify(latcell, loncell)

        deallocate(global_grid_index)
        nullify(global_grid_index, global_grid_map)
        nullify(lat_coord, lon_coord)

        ! Construct coordinate and grid objects for edge node grid (i.e., "mpas_edge").
        ! Standard MPAS coordinate and dimension names are used.

        call mpas_dynamical_core % get_variable_pointer(indextoedgeid, 'mesh', 'indexToEdgeID')
        call mpas_dynamical_core % get_variable_pointer(latedge, 'mesh', 'latEdge')
        call mpas_dynamical_core % get_variable_pointer(lonedge, 'mesh', 'lonEdge')

        allocate(global_grid_index(nedges_solve), stat=ierr)
        call check_allocate(ierr, subname, 'global_grid_index(nedges_solve)', 'dyn_grid', __LINE__)

        global_grid_index(:) = int(indextoedgeid(1:nedges_solve), kind_imap)

        lat_coord => horiz_coord_create('latEdge', 'nEdges', nedges_global, 'latitude', 'degrees_north', &
            1, nedges_solve, real(latedge, kind_r8) * rad_to_deg, map=global_grid_index)
        lon_coord => horiz_coord_create('lonEdge', 'nEdges', nedges_global, 'longitude', 'degrees_east', &
            1, nedges_solve, real(lonedge, kind_r8) * rad_to_deg, map=global_grid_index)

        allocate(global_grid_map(3, nedges_solve), stat=ierr)
        call check_allocate(ierr, subname, 'global_grid_map(3, nedges_solve)', 'dyn_grid', __LINE__)

        do i = 1, nedges_solve
            global_grid_map(1, i) = int(i, kind_imap)
            global_grid_map(2, i) = int(1, kind_imap)
            global_grid_map(3, i) = global_grid_index(i)
        end do

        call dyn_debug_print(debugout_verbose, 'Registering dynamics grid "mpas_edge" with id ' // &
            stringify([dyn_grid_id('mpas_edge')]))

        call cam_grid_register('mpas_edge', dyn_grid_id('mpas_edge'), lat_coord, lon_coord, global_grid_map, &
            unstruct=.true., block_indexed=.false.)

        nullify(indextoedgeid)
        nullify(latedge, lonedge)

        deallocate(global_grid_index)
        nullify(global_grid_index, global_grid_map)
        nullify(lat_coord, lon_coord)

        ! Construct coordinate and grid objects for vertex node grid (i.e., "mpas_vertex").
        ! Standard MPAS coordinate and dimension names are used.

        call mpas_dynamical_core % get_variable_pointer(indextovertexid, 'mesh', 'indexToVertexID')
        call mpas_dynamical_core % get_variable_pointer(latvertex, 'mesh', 'latVertex')
        call mpas_dynamical_core % get_variable_pointer(lonvertex, 'mesh', 'lonVertex')

        allocate(global_grid_index(nvertices_solve), stat=ierr)
        call check_allocate(ierr, subname, 'global_grid_index(nvertices_solve)', 'dyn_grid', __LINE__)

        global_grid_index(:) = int(indextovertexid(1:nvertices_solve), kind_imap)

        lat_coord => horiz_coord_create('latVertex', 'nVertices', nvertices_global, 'latitude', 'degrees_north', &
            1, nvertices_solve, real(latvertex, kind_r8) * rad_to_deg, map=global_grid_index)
        lon_coord => horiz_coord_create('lonVertex', 'nVertices', nvertices_global, 'longitude', 'degrees_east', &
            1, nvertices_solve, real(lonvertex, kind_r8) * rad_to_deg, map=global_grid_index)

        allocate(global_grid_map(3, nvertices_solve), stat=ierr)
        call check_allocate(ierr, subname, 'global_grid_map(3, nvertices_solve)', 'dyn_grid', __LINE__)

        do i = 1, nvertices_solve
           global_grid_map(1, i) = int(i, kind_imap)
           global_grid_map(2, i) = int(1, kind_imap)
           global_grid_map(3, i) = global_grid_index(i)
        end do

        call dyn_debug_print(debugout_verbose, 'Registering dynamics grid "mpas_vertex" with id ' // &
            stringify([dyn_grid_id('mpas_vertex')]))

        call cam_grid_register('mpas_vertex', dyn_grid_id('mpas_vertex'), lat_coord, lon_coord, global_grid_map, &
            unstruct=.true., block_indexed=.false.)

        nullify(indextovertexid)
        nullify(latvertex, lonvertex)

        deallocate(global_grid_index)
        nullify(global_grid_index, global_grid_map)
        nullify(lat_coord, lon_coord)

        call dyn_debug_print(debugout_debug, subname // ' completed')
    end subroutine define_cam_grid