subroutine regrid(srcField, dstField, missing, rc)
type (ESMF_Field), intent(in) :: srcField
type (ESMF_Field), intent(inout) :: dstField
real (kind=REAL32), optional, intent(in) :: missing
integer, optional, intent(out) :: rc
integer :: status
real(kind=REAL32), pointer :: src_array(:,:)
real(kind=REAL32), pointer :: dst_array(:,:)
type (ESMF_RouteHandle), pointer :: handle
character(len=:), allocatable :: local_key
character(len=:), allocatable :: global_key
integer, pointer :: mask(:,:)
type (ESMF_Array) :: mask_array
type (ESMF_Grid) :: grid
logical :: have_missing, any_missing
call ESMF_FieldGet(srcField, 0, src_array)
if (present(missing)) then
have_missing = any(missing == src_array)
call MPI_AllReduce(have_missing, any_missing, 1, MPI_LOGICAL, MPI_LOR, MPI_COMM_WORLD, ierror)
_VERIFY(ierror)
if (any_missing) then
local_key = run_length_encode(reshape(src_array,[size(src_array)]) == missing)
global_key = all_gather(local_key)
handle => route_handles%at(global_key)
if (.not. associated(handle)) then
allocate(handle)
call ESMF_FieldGet(srcfield, grid=grid, rc=status)
_VERIFY(status)
call ESMF_GridGetItem(grid, staggerLoc=ESMF_STAGGERLOC_CENTER, &
& itemflag=ESMF_GRIDITEM_MASK, array=mask_array, rc=status)
_VERIFY(status)
call ESMF_ArrayGet(mask_array, farrayptr=mask, rc=status)
_VERIFY(status)
where (src_array == missing)
mask = 0
elsewhere
mask = 1
end where
call ESMF_FieldRegridStore(srcField, dstField, &
& regridmethod=ESMF_REGRIDMETHOD_BILINEAR, lineType=ESMF_LINETYPE_GREAT_CIRCLE, &
& srcTermProcessing=srcTerm, &
& srcMaskValues = [0], &
& unmappedAction=ESMF_UNMAPPEDACTION_IGNORE, &
& routehandle=handle, rc=status)
_VERIFY(status)
call route_handles%insert(global_key, handle)
endif
call ESMF_FieldGet(dstField, 0, dst_array)
dst_array = missing
call ESMF_FieldRegrid(srcField, dstField, routeHandle=handle, &
& termorderflag=ESMF_TERMORDER_SRCSEQ, &
& zeroregion=ESMF_REGION_SELECT, &
& rc=status)
_VERIFY(status)
_RETURN(_SUCCESS)
else
handle => default_route_handle
end if
else
handle => default_route_handle
end if
call ESMF_FieldRegrid(srcField, dstField, routeHandle=handle, &
& termorderflag=ESMF_TERMORDER_SRCSEQ, rc=status)
_VERIFY(status)
_RETURN(_SUCCESS)
end subroutine regrid