diff --git a/sorc/chgres_cube.fd/search_util.F90 b/sorc/chgres_cube.fd/search_util.F90 index 33767fb75..e4d3d314f 100644 --- a/sorc/chgres_cube.fd/search_util.F90 +++ b/sorc/chgres_cube.fd/search_util.F90 @@ -117,6 +117,8 @@ subroutine search (field, mask, idim, jdim, tile, field_num, latitude, terrain_l default_value = 1.0 case (230) ! soil type on the input grid default_value = 11.0 + case (231) ! soil type at land ice points + default_value = 16.0 case default print*,'- FATAL ERROR. UNIDENTIFIED FIELD NUMBER : ', field_num call mpi_abort(mpi_comm_world, 77, ierr) diff --git a/sorc/chgres_cube.fd/surface.F90 b/sorc/chgres_cube.fd/surface.F90 index f373bebd4..5030ff2fb 100644 --- a/sorc/chgres_cube.fd/surface.F90 +++ b/sorc/chgres_cube.fd/surface.F90 @@ -139,6 +139,9 @@ module surface !< latent heat of fusion public :: surface_driver + public :: create_nst_esmf_fields + public :: nst_land_fill + public :: cleanup_target_nst_data contains @@ -212,14 +215,6 @@ subroutine surface_driver(localpet) call interp(localpet) - !if (.not. (vgtyp_from_climo .or. sotyp_from_climo)) then - !--------------------------------------------------------------------------------------------- - ! Check for points where smois is too high to be a land point at a land point - !--------------------------------------------------------------------------------------------- - ! - !call check_smois_water - !endif - !--------------------------------------------------------------------------------------------- ! Adjust soil/landice column temperatures for any change in elevation between ! the @@ -234,19 +229,6 @@ subroutine surface_driver(localpet) call rescale_soil_moisture - !if (.not. (vgtyp_from_climo .or. sotyp_from_climo)) then - !--------------------------------------------------------------------------------------------- - ! Check soil moisture again for mismatches after rescale_soil_moisture subroutine - !--------------------------------------------------------------------------------------------- - ! call check_smois_land - - !--------------------------------------------------------------------------------------------- - ! Replacing values various land surface parameters at points identified as mis-masked in - ! check_smois_land - !--------------------------------------------------------------------------------------------- - - ! call replace_land_sfcparams(localpet) - !endif !--------------------------------------------------------------------------------------------- ! Compute liquid portion of total soil moisture. !--------------------------------------------------------------------------------------------- @@ -402,6 +384,7 @@ subroutine interp(localpet) real(esmf_kind_r8), allocatable :: data_one_tile2(:,:) real(esmf_kind_r8), allocatable :: data_one_tile_3d(:,:,:) real(esmf_kind_r8), allocatable :: latitude_one_tile(:,:) + real(esmf_kind_r8), allocatable :: soil_type_target_grid_save(:,:) real(esmf_kind_r8), pointer :: canopy_mc_target_ptr(:,:) real(esmf_kind_r8), pointer :: c_d_target_ptr(:,:) real(esmf_kind_r8), pointer :: c_0_target_ptr(:,:) @@ -429,6 +412,7 @@ subroutine interp(localpet) real(esmf_kind_r8), pointer :: snow_liq_equiv_target_ptr(:,:) real(esmf_kind_r8), pointer :: soil_temp_target_ptr(:,:,:) real(esmf_kind_r8), pointer :: soil_type_from_input_ptr(:,:) + real(esmf_kind_r8), pointer :: soil_type_target_ptr(:,:) real(esmf_kind_r8), pointer :: soilm_tot_target_ptr(:,:,:) real(esmf_kind_r8), pointer :: srflag_target_ptr(:,:) real(esmf_kind_r8), pointer :: terrain_from_input_ptr(:,:) @@ -599,10 +583,12 @@ subroutine interp(localpet) allocate(data_one_tile(i_target,j_target)) allocate(data_one_tile_3d(i_target,j_target,lsoil_target)) allocate(mask_target_one_tile(i_target,j_target)) + allocate(soil_type_target_grid_save(i_target,j_target)) else allocate(data_one_tile(0,0)) allocate(data_one_tile_3d(0,0,0)) allocate(mask_target_one_tile(0,0)) + allocate(soil_type_target_grid_save(0,0)) endif !----------------------------------------------------------------------- @@ -693,15 +679,6 @@ subroutine interp(localpet) if(.not. vgtyp_from_climo) then - do tile = 1, num_tiles_target_grid - print*,"-CALL FieldGather VEG TYPE TARGET GRID" - call ESMF_FieldGather(veg_type_target_grid, data_one_tile, rootPet=0, tile=tile, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - - data_one_tile(:,:) = 0 - enddo - print*,"- CALL FieldRegrid VEG TYPE." call ESMF_FieldRegrid(veg_type_input_grid, & veg_type_target_grid, & @@ -1079,7 +1056,6 @@ subroutine interp(localpet) call ESMF_FieldScatter(soil_temp_target_grid, data_one_tile_3d, rootPet=0, tile=tile, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldScatter", rc) - enddo print*,"- CALL FieldRegridRelease." @@ -2023,6 +1999,28 @@ subroutine interp(localpet) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldGet", rc) + if (.not. sotyp_from_climo) then + print*,"- CALL FieldGather FOR SOIL TYPE TARGET GRID, TILE: ", tile + call ESMF_FieldGather(soil_type_target_grid,soil_type_target_grid_save,rootPet=0,tile=1, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldGather", rc) + + print*,"- CALL Field_Regrid for soil type over landice." + call ESMF_FieldRegrid(soil_type_input_grid, & + soil_type_target_grid, & + routehandle=regrid_landice, & + termorderflag=ESMF_TERMORDER_SRCSEQ, & + rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldRegrid", rc) + + print*,"- CALL FieldGet FOR SOIL TYPE TARGET GRID." + call ESMF_FieldGet(soil_type_target_grid, & + farrayPtr=soil_type_from_input_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldGet", rc) + endif + l = lbound(unmapped_ptr) u = ubound(unmapped_ptr) @@ -2031,6 +2029,7 @@ subroutine interp(localpet) soil_temp_target_ptr(i,j,:) = -9999.9 skin_temp_target_ptr(i,j) = -9999.9 terrain_from_input_ptr(i,j) = -9999.9 + if (.not.sotyp_from_climo) soil_type_from_input_ptr(i,j) = -9999.9 enddo if (localpet == 0) then @@ -2103,6 +2102,22 @@ subroutine interp(localpet) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldScatter", rc) + if (.not. sotyp_from_climo) then + print*,"- CALL FieldGather FOR SOIL TYPE TARGET GRID LAND, TILE: ",tile + call ESMF_FieldGather(soil_type_target_grid, data_one_tile,rootPet=0,tile=tile, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldGather", rc) + + if (localpet == 0) then + call search(data_one_tile, mask_target_one_tile, i_target, j_target,tile,231) + endif + + print*,"- CALL FieldScatter FOR SOIL TYPE TARGET GRID, TILE: ", tile + call ESMF_FieldScatter(soil_type_target_grid,data_one_tile,rootPet=0,tile=tile,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + endif + enddo deallocate (veg_type_target_one_tile) @@ -2178,6 +2193,17 @@ subroutine interp(localpet) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldRegrid", rc) + if (.not. sotyp_from_climo) then + print*,"- CALL Field_Regrid for soil type over land." + call ESMF_FieldRegrid(soil_type_input_grid, & + soil_type_target_grid, & + routehandle=regrid_land, & + zeroregion=ESMF_REGION_SELECT, & + termorderflag=ESMF_TERMORDER_SRCSEQ, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldRegrid", rc) + endif + print*,"- CALL Field_Regrid for soil type over land." call ESMF_FieldRegrid(soil_type_input_grid, & soil_type_from_input_grid, & @@ -2249,6 +2275,14 @@ subroutine interp(localpet) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldGet", rc) + if (.not. sotyp_from_climo) then + print*,"- CALL FieldGet FOR soil type target grid." + call ESMF_FieldGet(soil_type_target_grid, & + farrayPtr=soil_type_target_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldGet", rc) + endif + print*,"- CALL FieldGet FOR soil type from input grid." call ESMF_FieldGet(soil_type_from_input_grid, & farrayPtr=soil_type_from_input_ptr, rc=rc) @@ -2293,6 +2327,7 @@ subroutine interp(localpet) soil_temp_target_ptr(i,j,:) = -9999.9 skin_temp_target_ptr(i,j) = -9999.9 terrain_from_input_ptr(i,j) = -9999.9 + if (.not. sotyp_from_climo) soil_type_target_ptr(i,j) = -9999.9 soil_type_from_input_ptr(i,j) = -9999.9 veg_greenness_target_ptr(i,j) = -9999.9 max_veg_greenness_target_ptr(i,j) = -9999.9 @@ -2365,7 +2400,7 @@ subroutine interp(localpet) if (.not. sotyp_from_climo) then if (localpet==0) then - call search(data_one_tile, mask_target_one_tile, i_target, j_target, tile, 224,soilt_climo=data_one_tile2) + call search(data_one_tile2, mask_target_one_tile, i_target, j_target, tile, 224,soilt_climo=soil_type_target_grid_save) endif else if (localpet == 0 .and. maxval(data_one_tile) > 0 .and. (trim(external_model) .ne. "GFS" .or. trim(input_type) .ne. "grib2")) then @@ -2379,7 +2414,7 @@ subroutine interp(localpet) if (.not. sotyp_from_climo) then print*,"- CALL FieldScatter FOR SOIL TYPE TARGET GRID, TILE: ", tile - call ESMF_FieldScatter(soil_type_target_grid, data_one_tile, rootPet=0, tile=tile, rc=rc) + call ESMF_FieldScatter(soil_type_target_grid, data_one_tile2, rootPet=0, tile=tile, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldScatter", rc) endif @@ -2389,8 +2424,6 @@ subroutine interp(localpet) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldScatter", rc) - - if (.not. vgfrc_from_climo) then print*,"- CALL FieldGather FOR TARGET GRID VEG GREENNESS, TILE: ", tile call ESMF_FieldGather(veg_greenness_target_grid, data_one_tile, rootPet=0, tile=tile, rc=rc) @@ -2638,522 +2671,6 @@ subroutine calc_liq_soil_moisture end subroutine calc_liq_soil_moisture -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! This subroutine was previously used to correct for points with soil moisture that was -!! too high for land points. This happened when there was a mismatch between input and -!! target landmasks, specifically when input vegetation type was used to replace that -!! in the geogrid file. The functions performed by this subroutine are now performed -!! when the data is read in. Note that the target grid landmask is no longer modified -!! anywhere in the code, and the input data is modified instead. -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!subroutine check_smois_water -! -!use model_grid, only : landmask_target_grid -! -!use static_data, only : veg_type_target_grid, veg_greenness_target_grid, & -! soil_type_target_grid, max_veg_greenness_target_grid,& -! min_veg_greenness_target_grid, mxsno_albedo_target_grid, & -! alvsf_target_grid,alvwf_target_grid,& -! alnsf_target_grid,alnwf_target_grid -! -! implicit none -! -! integer :: clb(3), cub(3), i, j, rc -! -! integer(esmf_kind_r8), pointer :: landmask_ptr(:,:) -! -! real(esmf_kind_r8), pointer :: soilm_target_ptr(:,:,:), & -! alvsf_target_ptr(:,:), & -! alnsf_target_ptr(:,:), & -! alvwf_target_ptr(:,:), & -! alnwf_target_ptr(:,:), & -! veg_greenness_target_ptr(:,:), & -! min_veg_greenness_target_ptr(:,:), & -! max_veg_greenness_target_ptr(:,:), & -! canopy_mc_target_ptr(:,:), & -! mxsno_albedo_target_ptr(:,:), & -! soil_type_target_ptr(:,:), & -! veg_type_target_ptr(:,:) -! -! -! print*,"- CALL FieldGet FOR TARGET GRID LAND-SEA MASK." -! call ESMF_FieldGet(landmask_target_grid, & -! farrayPtr=landmask_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR SOIL MOIS TARGET GRID." -! call ESMF_FieldGet(soilm_tot_target_grid, & -! computationalLBound=clb, & -! computationalUBound=cub, & -! farrayPtr=soilm_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID SOIL TYPE." -! call ESMF_FieldGet(soil_type_target_grid, & -! farrayPtr=soil_type_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID VEG TYPE." -! call ESMF_FieldGet(veg_type_target_grid, & -! farrayPtr=veg_type_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID ALVSF." -! call ESMF_FieldGet(alvsf_target_grid, & -! farrayPtr=alvsf_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID ALNSF." -! call ESMF_FieldGet(alnsf_target_grid, & -! farrayPtr=alnsf_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID ALVWF." -! call ESMF_FieldGet(alvwf_target_grid, & -! farrayPtr=alvwf_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID ALNWF." -! call ESMF_FieldGet(alnwf_target_grid, & -! farrayPtr=alnwf_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID VEG FRAC." -! call ESMF_FieldGet(veg_greenness_target_grid, & -! farrayPtr=veg_greenness_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID MAX VEG FRAC." -! call ESMF_FieldGet(max_veg_greenness_target_grid, & -! farrayPtr=max_veg_greenness_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID MIN VEG FRAC." -! call ESMF_FieldGet(min_veg_greenness_target_grid, & -! farrayPtr=min_veg_greenness_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID CANOPY MC." -! call ESMF_FieldGet(canopy_mc_target_grid, & -! farrayPtr=canopy_mc_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! print*,"- CALL FieldGet FOR TARGET GRID SNOW ALBEDO." -! call ESMF_FieldGet(mxsno_albedo_target_grid, & -! farrayPtr=mxsno_albedo_target_ptr, rc=rc) -! if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & -! call error_handler("IN FieldGet", rc) -! -! do i =clb(1),cub(1) -! do j = clb(2),cub(2) -! if (landmask_ptr(i,j)==1 .and. soilm_target_ptr(i,j,1) > 0.75 .and. nint(veg_type_target_ptr(i,j)) /= veg_type_landice_target) then -! !write(*,'(a,2i5,a,i3,f5.2,2i3)') "CORRECTING G.P.",i,j," FROM LAND TO SEA VALUES; & -! ! curr landmask, soilm, stype, vtype = ",landmask_ptr(i,j),& -! ! soilm_target_ptr(i,j,1),nint(soil_type_target_ptr(i,j)), & -! ! nint(veg_type_target_ptr(i,j)) -! soil_type_target_ptr(i,j) = 0.0 -! veg_type_target_ptr(i,J) = 0.0 -! landmask_ptr(i,j) = 0 -! alvsf_target_ptr(i,j) = 0.06 -! alvwf_target_ptr(i,j) = 0.06 -! alnsf_target_ptr(i,j) = 0.06 -! alnwf_target_ptr(i,j) = 0.06 -! min_veg_greenness_target_ptr(i,j) = 0.0 -! max_veg_greenness_target_ptr(i,j) = 0.0 -! veg_greenness_target_ptr(i,j) = 0.0 -! mxsno_albedo_target_ptr(i,j) = 0.0 -! canopy_mc_target_ptr(i,j) = 0.0 -! endif -! enddo -! enddo -! -!end subroutine check_smois_water - -!> Check soil mositure -!! -!! When using vegetation type from the input data instead of the orography file, there -!! are frequently points with ~0 soil moisture at land points. For these points, set -!! values in all relevant target grid surface arrays to fill values (done in -!! check_smois_land) then run the search routine again to fill with appropriate values -!! from nearby points (done in replace_land_sfcparams). -!! -!! @author Larissa Reames -!! @author Jeff Beck -subroutine check_smois_land - -use model_grid, only : landmask_target_grid - -use static_data, only : veg_type_target_grid, veg_greenness_target_grid, & - soil_type_target_grid, max_veg_greenness_target_grid,& - min_veg_greenness_target_grid, mxsno_albedo_target_grid, & - alvsf_target_grid,alvwf_target_grid,& - alnsf_target_grid,alnwf_target_grid,& - facsf_target_grid,facwf_target_grid, & - slope_type_target_grid - - implicit none - - integer :: clb(3), cub(3), i, j, rc - - integer(esmf_kind_r8), pointer :: landmask_ptr(:,:) - - real(esmf_kind_r8), pointer :: soilm_target_ptr(:,:,:), & - soilt_target_ptr(:,:,:), & - alvsf_target_ptr(:,:), & - alnsf_target_ptr(:,:), & - alvwf_target_ptr(:,:), & - alnwf_target_ptr(:,:), & - veg_greenness_target_ptr(:,:), & - min_veg_greenness_target_ptr(:,:), & - max_veg_greenness_target_ptr(:,:), & - canopy_mc_target_ptr(:,:), & - mxsno_albedo_target_ptr(:,:), & - soil_type_target_ptr(:,:), & - veg_type_target_ptr(:,:), & - facsf_target_ptr(:,:), & - facwf_target_ptr(:,:), & - slope_type_target_ptr(:,:) - - - print*,"- CALL FieldGet FOR TARGET GRID LAND-SEA MASK." - call ESMF_FieldGet(landmask_target_grid, & - farrayPtr=landmask_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR SOIL MOIS TARGET GRID." - call ESMF_FieldGet(soilm_tot_target_grid, & - computationalLBound=clb, & - computationalUBound=cub, & - farrayPtr=soilm_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR SOIL TEMP TARGET GRID." - call ESMF_FieldGet(soil_temp_target_grid, & - farrayPtr=soilt_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID SOIL TYPE." - call ESMF_FieldGet(soil_type_target_grid, & - farrayPtr=soil_type_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID SOIL TYPE." - call ESMF_FieldGet(slope_type_target_grid, & - farrayPtr=slope_type_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID VEG TYPE." - call ESMF_FieldGet(veg_type_target_grid, & - farrayPtr=veg_type_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID ALVSF." - call ESMF_FieldGet(alvsf_target_grid, & - farrayPtr=alvsf_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID ALNSF." - call ESMF_FieldGet(alnsf_target_grid, & - farrayPtr=alnsf_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID ALVWF." - call ESMF_FieldGet(alvwf_target_grid, & - farrayPtr=alvwf_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID ALNWF." - call ESMF_FieldGet(alnwf_target_grid, & - farrayPtr=alnwf_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - -print*,"- CALL FieldGet FOR TARGET GRID FACSF." - call ESMF_FieldGet(facsf_target_grid, & - farrayPtr=facsf_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID FACWF." - call ESMF_FieldGet(facwf_target_grid, & - farrayPtr=facwf_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID VEG FRAC." - call ESMF_FieldGet(veg_greenness_target_grid, & - farrayPtr=veg_greenness_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID MAX VEG FRAC." - call ESMF_FieldGet(max_veg_greenness_target_grid, & - farrayPtr=max_veg_greenness_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID MIN VEG FRAC." - call ESMF_FieldGet(min_veg_greenness_target_grid, & - farrayPtr=min_veg_greenness_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID CANOPY MC." - call ESMF_FieldGet(canopy_mc_target_grid, & - farrayPtr=canopy_mc_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - print*,"- CALL FieldGet FOR TARGET GRID SNOW ALBEDO." - call ESMF_FieldGet(mxsno_albedo_target_grid, & - farrayPtr=mxsno_albedo_target_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - do i =clb(1),cub(1) - do j = clb(2),cub(2) - if (landmask_ptr(i,j)==1 .and. soilm_target_ptr(i,j,1) < 0.001 .and. nint(veg_type_target_ptr(i,j)) /= veg_type_landice_target) then !.and. & - WRITE(*,'(a,2i5,a,2i3)') " CORRECTING G.P. ",i,j," PARAMS FROM SEA TO LAND & - VALUES; curr stype,vtype=", nint(soil_type_target_ptr(i,j)),nint(veg_type_target_ptr(i,j)) - ! Set values to missing so that search function can then replace - ! them with nearby point values (see replace_land_sfcparams) - ! subroutine) - soilm_target_ptr(i,j,:) = -99999.9 - soilt_target_ptr(i,j,:) = -99999.9 - - soil_type_target_ptr(i,j) = -99999.9 - veg_type_target_ptr(i,J) = -99999.9 - - alvsf_target_ptr(i,j) = -99999.9 - alvwf_target_ptr(i,j) = -99999.9 - alnsf_target_ptr(i,j) = -99999.9 - alnwf_target_ptr(i,j) = -99999.9 - facsf_target_ptr(i,j) = -99999.9 - facwf_target_ptr(i,j) = -99999.9 - min_veg_greenness_target_ptr(i,j) = -99999.9 - max_veg_greenness_target_ptr(i,j) = -99999.9 - veg_greenness_target_ptr(i,j) = -99999.9 - mxsno_albedo_target_ptr(i,j) = -99999.9 - canopy_mc_target_ptr(i,j) = -99999.9 - slope_type_target_ptr(i,j) = -99999.9 - end if - enddo - enddo - !search (field, mask, idim, jdim, tile, field_num, - !call search(soilm_target_ptr(clb(1):cub(1),clb(2):cub(2), -end subroutine check_smois_land - -!> Replace bad surface points. -!! -!! When using vegetation type from the input data instead of the orography file, there -!! are frequently points with ~0 soil moisture at land points. For these points, set -!! values in all relevant target grid surface arrays to fill values (done in -!! check_smois_land) then run the search routine again to fill with appropriate values -!! from nearby points (done in replace_land_sfcparams). -!! -!! @param[in] localpet ESMF local persistent execution thread -!! @author Larissa Reames -!! @author Jeff Beck - subroutine replace_land_sfcparams(localpet) - - use search_util - use model_grid, only : lsoil_target, i_target, j_target, & - landmask_target_grid - use static_data, only : soil_type_target_grid, & - alvsf_target_grid, & - alvwf_target_grid, & - alnsf_target_grid, & - alnwf_target_grid, & - facsf_target_grid, & - facwf_target_grid, & - mxsno_albedo_target_grid, & - max_veg_greenness_target_grid, & - min_veg_greenness_target_grid, & - slope_type_target_grid, & - veg_greenness_target_grid, & - veg_type_target_grid - -!i_input, j_input, input_grid - implicit none - integer, intent(in) :: localpet - !character(len=1000) :: msg - integer :: rc, k_soil - integer(esmf_kind_i8) :: maskdata_one_tile(i_target,j_target) - real(esmf_kind_r8) :: soiltdata_one_tile_3d(i_target,j_target,lsoil_target), & - soilmdata_one_tile_3d(i_target,j_target,lsoil_target), & - soiltype_one_tile(i_target,j_target), & - alvsf_one_tile(i_target,j_target), & - alvwf_one_tile(i_target,j_target), & - alnsf_one_tile(i_target,j_target), & - alnwf_one_tile(i_target,j_target), & - facsf_one_tile(i_target,j_target), & - facwf_one_tile(i_target,j_target), & - mxsno_albedo_one_tile(i_target,j_target), & - max_veg_greenness_one_tile(i_target,j_target), & - min_veg_greenness_one_tile(i_target,j_target), & - slope_type_one_tile(i_target,j_target), & - veg_greenness_one_tile(i_target,j_target), & - veg_type_one_tile(i_target,j_target), & - canopy_mc_one_tile(i_target,j_target), & - tmp(i_target,j_target) - - !if (localpet==0) PRINT *, "STARTING SUBROUTINE replace_land_sfcparams" - call ESMF_FieldGather(landmask_target_grid, maskdata_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - - -! Now get all variables to call search routine for - call ESMF_FieldGather(soil_temp_target_grid, soiltdata_one_tile_3d, rootPet=0, tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(soilm_tot_target_grid, soilmdata_one_tile_3d, rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(soil_type_target_grid, soiltype_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(alvsf_target_grid, alvsf_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(alvwf_target_grid, alvwf_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(alnsf_target_grid, alnsf_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(alnwf_target_grid, alnwf_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(facsf_target_grid, facsf_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(facwf_target_grid, facwf_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(mxsno_albedo_target_grid,mxsno_albedo_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(max_veg_greenness_target_grid, max_veg_greenness_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(min_veg_greenness_target_grid, min_veg_greenness_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(slope_type_target_grid, slope_type_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(veg_greenness_target_grid, veg_greenness_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(veg_type_target_grid, veg_type_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", rc) - call ESMF_FieldGather(canopy_mc_target_grid,canopy_mc_one_tile,rootPet=0,tile=1,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldGather", rc) - if (localpet == 0) then - ! 2d vars - call search(soiltype_one_tile,maskdata_one_tile,i_target,j_target,1,224) - call search(alvsf_one_tile,maskdata_one_tile,i_target,j_target,1,0) - call search(alvwf_one_tile,maskdata_one_tile,i_target,j_target,1,0) - call search(alnsf_one_tile,maskdata_one_tile,i_target,j_target,1,0) - call search(alnwf_one_tile,maskdata_one_tile,i_target,j_target,1,0) - call search(facsf_one_tile,maskdata_one_tile,i_target,j_target,1,0) - call search(facwf_one_tile,maskdata_one_tile,i_target,j_target,1,0) - call search(mxsno_albedo_one_tile,maskdata_one_tile,i_target,j_target,1,0) - call search(max_veg_greenness_one_tile,maskdata_one_tile,i_target,j_target,1,226) - call search(min_veg_greenness_one_tile,maskdata_one_tile,i_target,j_target,1,226) - call search(slope_type_one_tile,maskdata_one_tile,i_target,j_target,1,0) - call search(veg_greenness_one_tile,maskdata_one_tile,i_target,j_target,1,226) - call search(veg_type_one_tile,maskdata_one_tile,i_target,j_target,1,225) - call search(canopy_mc_one_tile,maskdata_one_tile,i_target,j_target,1,223) - ! 3d vars - do k_soil = 1, lsoil_target - tmp = soiltdata_one_tile_3d(:,:,k_soil) - call search(tmp,maskdata_one_tile,i_target,j_target,1,85) - soiltdata_one_tile_3d(:,:,k_soil) = tmp - - tmp = soilmdata_one_tile_3d(:,:,k_soil) - call search(tmp,maskdata_one_tile,i_target,j_target,1,86) - soilmdata_one_tile_3d(:,:,k_soil) = tmp - end do - end if ! localpet - -! scatter data back to procs - call ESMF_FieldScatter(soilm_tot_target_grid, soilmdata_one_tile_3d, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(soil_temp_target_grid, soiltdata_one_tile_3d, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(soil_type_target_grid, soiltype_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(alvsf_target_grid, alvsf_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(alvwf_target_grid, alvwf_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(alnsf_target_grid, alnsf_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(alnwf_target_grid, alnwf_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(facsf_target_grid, facsf_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(facwf_target_grid, facwf_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(mxsno_albedo_target_grid, mxsno_albedo_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(max_veg_greenness_target_grid, max_veg_greenness_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(min_veg_greenness_target_grid, min_veg_greenness_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(slope_type_target_grid, slope_type_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(veg_greenness_target_grid, veg_greenness_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(veg_type_target_grid, veg_type_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - call ESMF_FieldScatter(canopy_mc_target_grid, canopy_mc_one_tile, rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - - -end subroutine replace_land_sfcparams - !> Calculate supercooled soil moisture !! !! Calculate amount of supercooled liquid soil water content if @@ -4072,203 +3589,74 @@ subroutine nst_land_fill implicit none integer(esmf_kind_i8), pointer :: mask_ptr(:,:) - integer :: rc + integer :: rc,i real(esmf_kind_r8), pointer :: data_ptr(:,:) real(esmf_kind_r8), pointer :: skint_ptr(:,:) + type(esmf_field) :: temp_field + type(esmf_fieldbundle) :: nst_bundle + print*,"- CALL FieldGet FOR TARGET GRID LANDMASK." call ESMF_FieldGet(landmask_target_grid, & farrayPtr=mask_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - -! c_d - - print*,"- CALL FieldGet FOR C_D." - call ESMF_FieldGet(c_d_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! c_0 - - print*,"- CALL FieldGet FOR C_0." - call ESMF_FieldGet(c_0_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! d_conv - - print*,"- CALL FieldGet FOR D_CONV." - call ESMF_FieldGet(d_conv_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! dt_cool - - print*,"- CALL FieldGet FOR DT_COOL." - call ESMF_FieldGet(dt_cool_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& call error_handler("IN FieldGet", rc) + + nst_bundle = ESMF_FieldBundleCreate(name="nst_bundle", rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldBundleCreate", rc) - where(mask_ptr /= 0) data_ptr = 0.0 - -! ifd - - print*,"- CALL FieldGet FOR IFD." - call ESMF_FieldGet(ifd_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! qrain - - print*,"- CALL FieldGet FOR QRAIN." - call ESMF_FieldGet(qrain_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! tref + call ESMF_FieldBundleAdd(nst_bundle, (/c_d_target_grid,c_0_target_grid,d_conv_target_grid, & + dt_cool_target_grid,ifd_target_grid,qrain_target_grid,& + w_d_target_grid,w_0_target_grid,xs_target_grid,xt_target_grid,& + xu_target_grid,xv_target_grid,xtts_target_grid,xzts_target_grid, & + z_c_target_grid, zm_target_grid/), rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldBundleAdd", rc) print*,"- CALL FieldGet FOR TREF." call ESMF_FieldGet(tref_target_grid, & farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& call error_handler("IN FieldGet", rc) print*,"- CALL FieldGet FOR SKIN T." call ESMF_FieldGet(skin_temp_target_grid, & farrayPtr=skint_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& call error_handler("IN FieldGet", rc) where(mask_ptr /= 0) data_ptr = skint_ptr -! w_d - - print*,"- CALL FieldGet FOR W_D." - call ESMF_FieldGet(w_d_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! w_0 - - print*,"- CALL FieldGet FOR W_0." - call ESMF_FieldGet(w_0_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! xs - - print*,"- CALL FieldGet FOR XS." - call ESMF_FieldGet(xs_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! xt - - print*,"- CALL FieldGet FOR XT." - call ESMF_FieldGet(xt_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! xu - - print*,"- CALL FieldGet FOR XU." - call ESMF_FieldGet(xu_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! xv - - print*,"- CALL FieldGet FOR XV." - call ESMF_FieldGet(xv_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - ! xz print*,"- CALL FieldGet FOR XZ." call ESMF_FieldGet(xz_target_grid, & farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& call error_handler("IN FieldGet", rc) where(mask_ptr /= 0) data_ptr = 30.0 -! xtts - - print*,"- CALL FieldGet FOR XTTS." - call ESMF_FieldGet(xtts_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! xzts - - print*,"- CALL FieldGet FOR XZTS." - call ESMF_FieldGet(xzts_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! z_c - - print*,"- CALL FieldGet FOR Z_C." - call ESMF_FieldGet(z_c_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) - - where(mask_ptr /= 0) data_ptr = 0.0 - -! zm - - print*,"- CALL FieldGet FOR ZM." - call ESMF_FieldGet(zm_target_grid, & - farrayPtr=data_ptr, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) + do i = 1,16 + + call ESMF_FieldBundleGet(nst_bundle,i,temp_field,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldBundleGet", rc) + + call ESMF_FieldGet(temp_field,farrayPtr=data_ptr,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldGet", rc) + + where(mask_ptr /= 0) data_ptr = 0.0 - where(mask_ptr /= 0) data_ptr = 0.0 + enddo + call ESMF_FieldBundleDestroy(nst_bundle,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldBundleDestroy", rc) + end subroutine nst_land_fill !> Create ESMF fields for the target grid surface variables @@ -4622,6 +4010,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID C_D." c_d_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='c_d', & staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4629,6 +4018,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID C_0." c_0_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='c_0', & staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4636,6 +4026,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID D_CONV." d_conv_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='d_conv',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4643,6 +4034,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID DT_COOL." dt_cool_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='dt_cool',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4650,6 +4042,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID IFD." ifd_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='ifd',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4657,6 +4050,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID QRAIN." qrain_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='qrain',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4664,6 +4058,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID TREF." tref_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='tref',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4671,6 +4066,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID W_D." w_d_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='w_d',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4678,6 +4074,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID W_0." w_0_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='w_0',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4685,6 +4082,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID XS." xs_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='xs',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4692,6 +4090,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID XT." xt_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='xt',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4699,6 +4098,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID XU." xu_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='xu',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4706,6 +4106,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID XV." xv_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='xv',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4713,6 +4114,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID XZ." xz_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='xz',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4720,6 +4122,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID XTTS." xtts_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='xtts',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4727,6 +4130,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID XZTS." xzts_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='xzts',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4734,6 +4138,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID Z_C." z_c_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='z_c',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) @@ -4741,6 +4146,7 @@ subroutine create_nst_esmf_fields print*,"- CALL FieldCreate FOR TARGET GRID ZM." zm_target_grid = ESMF_FieldCreate(target_grid, & typekind=ESMF_TYPEKIND_R8, & + name='zm',& staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldCreate", rc) diff --git a/tests/chgres_cube/CMakeLists.txt b/tests/chgres_cube/CMakeLists.txt index 0a593ddfd..6e679d541 100644 --- a/tests/chgres_cube/CMakeLists.txt +++ b/tests/chgres_cube/CMakeLists.txt @@ -106,6 +106,15 @@ add_mpi_test(chgres_cube-ftst_read_nst_netcdf NUMPROCS 1 TIMEOUT 60) +add_executable(ftst_surface_nst_landfill ftst_surface_nst_landfill.F90) +target_link_libraries(ftst_surface_nst_landfill chgres_cube_lib) + +# Cause test to be run with MPI. +add_mpi_test(chgres_cube-ftst_surface_nst_landfill + EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/ftst_surface_nst_landfill + NUMPROCS 1 + TIMEOUT 60) + add_executable(ftst_read_atm_gaussian_netcdf ftst_read_atm_gaussian_netcdf.F90) target_link_libraries(ftst_read_atm_gaussian_netcdf chgres_cube_lib) diff --git a/tests/chgres_cube/ftst_surface_interp.F90 b/tests/chgres_cube/ftst_surface_interp.F90 new file mode 100644 index 000000000..fdc9a91a0 --- /dev/null +++ b/tests/chgres_cube/ftst_surface_interp.F90 @@ -0,0 +1,418 @@ + program surface_interp + +! Unit test for surface routine interp that regrids surface +! variables from input to target grid. +! +! Author: Larissa Reames, OU CIMMS/NOAA NSSL + + use esmf + + use program_setup, only : sotyp_from_climo, & + vgtyp_from_climo + + use model_grid, only : i_input, j_input, & + input_grid, & + latitude_input_grid, & + longitude_input_grid, & + i_target, j_target, & + target_grid, num_tiles_target_grid, & + latitude_target_grid, & + longitude_target_grid, & + landmask_target_grid, & + seamask_target_grid, & + terrain_target_grid, & + cleanup_input_target_grid_data + + use static_data, only: create_static_fields, & + soil_type_target_grid, & + veg_type_target_grid, & + cleanup_static_fields + + use surface, only : create_surface_esmf_fields, & + interp, & + cleanup_target_sfc_data + + use input_data, only : init_sfc_esmf_fields, & + soil_type_input_grid, & + veg_type_input_grid, & + landsea_mask_input_grid, & + terrain_input_grid, & + t2m_input_grid, & + cleanup_input_sfc_data + + implicit none + + integer, parameter :: IPTS_INPUT=4 + integer, parameter :: JPTS_INPUT=3 + integer, parameter :: IPTS_TARGET=8 + integer, parameter :: JPTS_TARGET=5 + + real, parameter :: EPSILON=0.0001 + real(esmf_kind_r8) :: deltalon + + integer :: clb(4), cub(4) + integer :: ierr, localpet, npets, rc + integer :: i, j, k + + integer(esmf_kind_i8), pointer :: mask_target_ptr(:,:) + real(esmf_kind_r8), allocatable :: latitude(:,:), longitude(:,:) + real(esmf_kind_r8), allocatable :: mask_input(:,:) + integer(esmf_kind_i8), allocatable :: mask_target(:,:), & + seamask_target(:,:) + real(esmf_kind_r8), allocatable :: sotyp_input(:,:), & + vgtyp_input(:,:), & + terrain_input(:,:), & + t2m_input(:,:) + real(esmf_kind_r8), allocatable :: sotyp_correct(:,:), & + sotyp_target(:,:), & + vgtyp_target(:,:), & + vgtyp_correct(:,:), & + terrain_correct(:,:) + real(esmf_kind_r8), pointer :: lon_ptr(:,:), & + lat_ptr(:,:) + real(esmf_kind_r8), pointer :: lon_corner_ptr(:,:), & + lat_corner_ptr(:,:) + type(esmf_vm) :: vm + type(esmf_polekind_flag) :: polekindflag(2) + + print*,"Starting test of surface interp." + + call mpi_init(ierr) + + call ESMF_Initialize(rc=ierr) + + call ESMF_VMGetGlobal(vm, rc=ierr) + + call ESMF_VMGet(vm, localPet=localpet, petCount=npets, rc=ierr) + + sotyp_from_climo = .False. + vgtyp_from_climo = .False. + + !--------------------------------------------------------------------! + !----------------- Setup Input Grid & Coordinates -------------------! + !--------------------------------------------------------------------! + + i_input = IPTS_INPUT + j_input = JPTS_INPUT + + polekindflag(1:2) = ESMF_POLEKIND_MONOPOLE + + input_grid = ESMF_GridCreateNoPeriDim(maxIndex=(/i_input,j_input/), & + indexflag=ESMF_INDEX_GLOBAL, rc=rc) + + allocate(latitude(i_input,j_input)) + allocate(longitude(i_input,j_input)) + + ! This is a random regional grid. I tried a global grid here but it had an unstable + ! solution. + + deltalon = 2.0_esmf_kind_r8 + do i = 1, i_input + longitude(i,:) = 90+real((i-1),kind=esmf_kind_r8) * deltalon + enddo + + do j = 1, j_input + latitude(:,j) = 35.0-real((j-1),kind=esmf_kind_r8) * deltalon + end do + + call ESMF_GridAddCoord(input_grid, & + staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridAddCoord", rc) + + call ESMF_GridGetCoord(input_grid, & + staggerLoc=ESMF_STAGGERLOC_CENTER, & + coordDim=1, & + farrayPtr=lon_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridGetCoord", rc) + + print*,"- CALL GridGetCoord FOR INPUT GRID Y-COORD." + call ESMF_GridGetCoord(input_grid, & + staggerLoc=ESMF_STAGGERLOC_CENTER, & + coordDim=2, & + computationalLBound=clb, & + computationalUBound=cub, & + farrayPtr=lat_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridGetCoord", rc) + + do j = clb(2), cub(2) + do i = clb(1), cub(1) + lon_ptr(i,j) = longitude(i,j) + if (lon_ptr(i,j) > 360.0_esmf_kind_r8) lon_ptr(i,j) = lon_ptr(i,j) - 360.0_esmf_kind_r8 + lat_ptr(i,j) = latitude(i,j) + enddo + enddo + nullify(lat_ptr,lon_ptr) + +! Create staggered coordinates for conservative regridding + print*,"- CALL GridAddCoord FOR INPUT GRID." + call ESMF_GridAddCoord(input_grid, & + staggerloc=ESMF_STAGGERLOC_CORNER, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridAddCoord", rc) + + print*,"- CALL GridGetCoord FOR INPUT GRID X-COORD." + call ESMF_GridGetCoord(input_grid, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + coordDim=1, & + farrayPtr=lon_corner_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridGetCoord", rc) + + print*,"- CALL GridGetCoord FOR INPUT GRID Y-COORD." + call ESMF_GridGetCoord(input_grid, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + coordDim=2, & + computationalLBound=clb, & + computationalUBound=cub, & + farrayPtr=lat_corner_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridGetCoord", rc) + + do j = clb(2), cub(2) + do i = clb(1), cub(1) + if (i == i_input+1) then + lon_corner_ptr(i,j) = longitude(i_input,1) + (0.5_esmf_kind_r8*deltalon) + else + lon_corner_ptr(i,j) = longitude(i,1) - (0.5_esmf_kind_r8*deltalon) + endif + + if (j == j_input+1) then + lat_corner_ptr(i,j) = latitude(1,j_input) +(0.5_esmf_kind_r8*deltalon) + else + lat_corner_ptr(i,j) = latitude(1,j) -(0.5_esmf_kind_r8*deltalon) + endif + enddo + enddo + + latitude_input_grid = ESMF_FieldCreate(input_grid, & + typekind=ESMF_TYPEKIND_R8, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="input_grid_latitude", & + rc=rc) + + longitude_input_grid = ESMF_FieldCreate(input_grid, & + typekind=ESMF_TYPEKIND_R8, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="input_grid_longitude", & + rc=rc) + + call ESMF_FieldScatter(longitude_input_grid, longitude, rootpet=0, rc=rc) + call ESMF_FieldScatter(latitude_input_grid, latitude, rootpet=0, rc=rc) + deallocate(latitude, longitude) + nullify(lat_corner_ptr, lon_corner_ptr) + + !Initializes surface ESMF fields + call init_sfc_esmf_fields + + !Allocate and fill in the fields on the input grid that we need to create soil type + allocate(mask_input(i_input,j_input)) + allocate(sotyp_input(i_input,j_input)) + allocate(vgtyp_input(i_input,j_input)) + allocate(terrain_input(i_input,j_input)) + + mask_input = reshape((/0,1,1,1, 0,1,1,1, 0,1,1,0/),(/i_input,j_input/)) + sotyp_input = reshape((/0.,16.,4.,16., 0.,3.,5.,16., 0.,3.,5.,0./),(/i_input,j_input/)) + vgtyp_input = reshape((/0.,15.,5.,15., 0.,5.,6.,15., 0.,5.,6.,0./),(/i_input,j_input/)) + terrain_input = reshape((/0.,20.,20.,20., 0.,20.,20.,20., 0.,20., 20.,0./),(/i_input,j_input/)) + + call ESMF_FieldScatter(landsea_mask_input_grid,mask_input,rootpet=0,rc=rc) + call ESMF_FieldScatter(soil_type_input_grid,sotyp_input,rootpet=0,rc=rc) + call ESMF_FieldScatter(veg_type_input_grid,vgtyp_input,rootpet=0,rc=rc) + call ESMF_FieldScatter(terrain_input_grid,terrain_input,rootpet=0,rc=rc) + + deallocate(mask_input,sotyp_input,vgtyp_input,terrain_input) + + !--------------------------------------------------------------------! + !---------------- Setup Target Grid & Coordinates -------------------! + !--------------------------------------------------------------------! + + i_target = IPTS_TARGET + j_target = JPTS_TARGET + + num_tiles_target_grid = 1 + target_grid = ESMF_GridCreate1PeriDim(maxIndex=(/i_target,j_target/), & + indexflag=ESMF_INDEX_GLOBAL, rc=rc) + + allocate(latitude(i_target,j_target)) + allocate(longitude(i_target,j_target)) + + ! Regional grid that fits within the input regional grid but with smaller grid cells + deltalon = 0.5 + do i = 1, i_target + longitude(i,:) = 91.1_esmf_kind_r8 + real((i-1),kind=esmf_kind_r8) * deltalon + enddo + + do i = 1, j_target + latitude(:,i) = 34.1_esmf_kind_r8 - real((i-1),kind=esmf_kind_r8) * deltalon + enddo + + call ESMF_GridAddCoord(target_grid, & + staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridAddCoord", rc) + + call ESMF_GridGetCoord(target_grid, & + staggerLoc=ESMF_STAGGERLOC_CENTER, & + coordDim=1, & + farrayPtr=lon_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridGetCoord", rc) + + call ESMF_GridGetCoord(target_grid, & + staggerLoc=ESMF_STAGGERLOC_CENTER, & + coordDim=2, & + computationalLBound=clb, & + computationalUBound=cub, & + farrayPtr=lat_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridGetCoord", rc) + + do j = clb(2), cub(2) + do i = clb(1), cub(1) + lon_ptr(i,j) = longitude(i,j) + if (lon_ptr(i,j) > 360.0_esmf_kind_r8) lon_ptr(i,j) = lon_ptr(i,j) -360.0_esmf_kind_r8 + lat_ptr(i,j) = latitude(i,j) + enddo + enddo + nullify(lat_ptr,lon_ptr) + + call ESMF_GridAddCoord(target_grid, & + staggerloc=ESMF_STAGGERLOC_CORNER, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridAddCoord", rc) + + call ESMF_GridGetCoord(target_grid, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + coordDim=1, & + farrayPtr=lon_corner_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridGetCoord", rc) + + call ESMF_GridGetCoord(target_grid, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + coordDim=2, & + computationalLBound=clb, & + computationalUBound=cub, & + farrayPtr=lat_corner_ptr, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridGetCoord", rc) + + ! Create staggered coordinates for regional target grid + do j = clb(2), cub(2) + do i = clb(1), cub(1) + if (i == i_target+1) then + lon_corner_ptr(i,j) = longitude(i_input,1) + (0.5_esmf_kind_r8*deltalon) + else + lon_corner_ptr(i,j) = longitude(i,1) - (0.5_esmf_kind_r8*deltalon) + endif + + if (j == j_target+1) then + lat_corner_ptr(i,j) = latitude(1,j_input) +(0.5_esmf_kind_r8*deltalon) + else + lat_corner_ptr(i,j) = latitude(1,j) -(0.5_esmf_kind_r8*deltalon) + endif + enddo + enddo + + latitude_target_grid = ESMF_FieldCreate(target_grid, & + typekind=ESMF_TYPEKIND_R8, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="target_grid_latitude", & + rc=rc) + + longitude_target_grid = ESMF_FieldCreate(target_grid, & + typekind=ESMF_TYPEKIND_R8, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="input_grid_longitude", & + rc=rc) + + call ESMF_FieldScatter(longitude_target_grid, longitude, rootpet=0, rc=rc) + call ESMF_FieldScatter(latitude_target_grid, latitude, rootpet=0, rc=rc) + deallocate(latitude, longitude) + nullify(lat_corner_ptr, lon_corner_ptr) + + ! Create the fields for the target grid land and seamask since these would normally + ! be created in the appropriate model_grid subroutine + + print*,"- CALL FieldCreate FOR TARGET GRID LANDMASK." + landmask_target_grid = ESMF_FieldCreate(target_grid, & + typekind=ESMF_TYPEKIND_I8, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="target_grid_landmask", rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldCreate",rc) + + print*,"- CALL FieldCreate FOR TARGET GRID SEAMASK." + seamask_target_grid = ESMF_FieldCreate(target_grid, & + typekind=ESMF_TYPEKIND_I8, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="target_grid_seamask", rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldCreate", rc) + + ! Initialize other surface fields on the target grid + call create_surface_esmf_fields() + call create_static_fields() + + ! Create masks on the target grid and the correcte (expected) soil type on the target grid + ! to check against what returns from interp + + allocate(mask_target(i_target,j_target)) + allocate(seamask_target(i_target,j_target)) + allocate(sotyp_target(i_target,j_target)) + allocate(sotyp_correct(i_target,j_target)) + + mask_target(:,1) = (/0,0,1,1,1,1,1,1/) + mask_target(:,2) = (/0,0,1,1,1,1,1,1/) + mask_target(:,3) = (/0,0,1,1,1,1,1,1/) + mask_target(:,4) = (/0,0,1,1,1,1,0,0/) + mask_target(:,5) = (/0,0,1,1,1,1,0,0/) + +!vgtyp_correct = reshape((/0., 0., 15.,15.,5., 5., 5., 5., & +! 0., 0., 5., 5., 6., 6., 6., 6., & +! 0., 0., 5., 5., 6., 6., 6., 6., & +! 0., 0., 5., 5., 6., 6., 0., 0., & +! 0., 0., 5., 5., 6., 6., 0., 0. /),(/i_target,j_target/)) + sotyp_correct = reshape((/0., 0.,16.,16., 4., 4., 4., 4., & + 0., 0., 3., 3., 5., 5., 5., 5., & + 0., 0., 3., 3., 5., 5., 5., 5., & + 0., 0., 3., 3., 5., 5., 0., 0., & + 0., 0., 3., 3., 5., 5., 0., 0. /),(/i_target,j_target/)) + seamask_target = 0 + where(mask_target .eq. 0) seamask_target = 1 + + call ESMF_FieldScatter(landmask_target_grid,mask_target,rootpet=0,rc=rc) + call ESMF_FieldScatter(seamask_target_grid,seamask_target,rootpet=0,rc=rc) + + !Call the routine to unit test. + call interp(localpet) + + call ESMF_FieldGather(soil_type_target_grid, sotyp_target, rootPet=0, rc=rc) + + print*,"Check results." + + if (any((abs(sotyp_target - sotyp_correct)) > EPSILON)) then + print*,'TEST FAILED ' + print*,'ARRAY SHOULD BE:', sotyp_correct + print*,'ARRAY FROM TEST:', sotyp_target + stop 2 + endif + + + print*,"OK" + + deallocate(mask_target, sotyp_target, sotyp_correct,seamask_target) + + call cleanup_static_fields + call cleanup_input_sfc_data + call cleanup_target_sfc_data + call cleanup_input_target_grid_data + call ESMF_finalize(endflag=ESMF_END_KEEPMPI) + call mpi_finalize(rc) + + print*,"SUCCESS!" + + end program surface_interp diff --git a/tests/chgres_cube/ftst_surface_nst_landfill.F90 b/tests/chgres_cube/ftst_surface_nst_landfill.F90 new file mode 100644 index 000000000..5eac66cc4 --- /dev/null +++ b/tests/chgres_cube/ftst_surface_nst_landfill.F90 @@ -0,0 +1,222 @@ + program surface_nst_landfill + +! Unit test for surface routine interp that regrids surface +! variables from input to target grid. +! +! Author: Larissa Reames, OU CIMMS/NOAA NSSL + + use esmf + + use model_grid, only : i_target, j_target, & + target_grid, num_tiles_target_grid, & + landmask_target_grid + + use surface, only : skin_temp_target_grid, & + nst_land_fill, & + create_nst_esmf_fields, & + cleanup_target_nst_data, & + c_d_target_grid, & + c_0_target_grid, & + d_conv_target_grid, & + dt_cool_target_grid, & + ifd_target_grid, & + qrain_target_grid, & + tref_target_grid, & + w_d_target_grid, & + w_0_target_grid, & + xs_target_grid, & + xt_target_grid, & + xu_target_grid, & + xv_target_grid, & + xz_target_grid, & + xtts_target_grid, & + xzts_target_grid, & + z_c_target_grid, & + zm_target_grid + + + implicit none + + integer, parameter :: IPTS_TARGET=4 + integer, parameter :: JPTS_TARGET=4 + + real, parameter :: EPSILON=0.0001 + real(esmf_kind_r8) :: deltalon, & + init_val = -999.9 + + integer :: ierr, localpet, npets, rc + integer :: i + + character(len=50) :: fname + + integer(esmf_kind_i8), pointer :: mask_target_ptr(:,:) + integer(esmf_kind_i8), allocatable :: mask(:,:) + + real(esmf_kind_r8), pointer :: skin_temp_ptr(:,:), & + tmp_ptr(:,:) + + real(esmf_kind_r8), allocatable :: skin_temp(:,:), & + tmp_array_2d(:,:), & + nst_field_correct(:,:), & + tref_correct(:,:),& + xz_correct(:,:) + + type(esmf_vm) :: vm + type(esmf_field) :: tmp_field + type(esmf_fieldbundle) :: nst_bundle + + print*,"Starting test of nst_land_fill." + + call mpi_init(ierr) + + call ESMF_Initialize(rc=ierr) + + call ESMF_VMGetGlobal(vm, rc=ierr) + + call ESMF_VMGet(vm, localPet=localpet, petCount=npets, rc=ierr) + + !--------------------------------------------------------------------! + !---------------- Setup Target Grid & Coordinates -------------------! + !--------------------------------------------------------------------! + + i_target = IPTS_TARGET + j_target = JPTS_TARGET + + num_tiles_target_grid = 1 + target_grid = ESMF_GridCreate1PeriDim(maxIndex=(/i_target,j_target/), & + indexflag=ESMF_INDEX_GLOBAL, rc=rc) + + call ESMF_GridAddCoord(target_grid, & + staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN GridAddCoord", rc) + + landmask_target_grid = ESMF_FieldCreate(target_grid, & + typekind=ESMF_TYPEKIND_I8, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="target_grid_landmask", & + rc=rc) + + skin_temp_target_grid = ESMF_FieldCreate(target_grid, & + typekind=ESMF_TYPEKIND_R8, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="target_grid_skin_temp", & + rc=rc) + + call create_nst_esmf_fields + + allocate(mask(i_target,j_target)) + allocate(skin_temp(i_target,j_target)) + allocate(nst_field_correct(i_target,j_target)) + allocate(tref_correct(i_target,j_target)) + allocate(xz_correct(i_target,j_target)) + + mask = reshape((/0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0/),(/i_target,j_target/)) + skin_temp = reshape((/280., 280., 280., 280., & + 280., 290., 290., 280., & + 280., 290., 290., 280., & + 280., 280., 280., 280./),(/i_target,j_target/)) + call ESMF_FieldScatter(landmask_target_grid, mask, rootpet=0, rc=rc) + call ESMF_FieldScatter(skin_temp_target_grid, skin_temp, rootpet=0, rc=rc) + deallocate(mask, skin_temp) + + nst_field_correct = reshape((/-999.9, -999.9, -999.9, -999.9, & + -999.9, 0., 0., -999.9, & + -999.9, 0., 0., -999.9, & + -999.9, -999.9, -999.9, -999.9/),(/i_target,j_target/)) + + tref_correct = reshape((/-999.9, -999.9, -999.9, -999.9, & + -999.9, 290.0, 290.0, -999.9, & + -999.9, 290.0, 290.0, -999.9, & + -999.9, -999.9, -999.9, -999.9/),(/i_target,j_target/)) + + xz_correct = reshape((/-999.9, -999.9, -999.9, -999.9, & + -999.9, 30.0, 30.0, -999.9, & + -999.9, 30.0, 30.0, -999.9, & + -999.9, -999.9, -999.9, -999.9/),(/i_target,j_target/)) + + nst_bundle = ESMF_FieldBundleCreate(name="nst_bundle", rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldBundleCreate", rc) + + call ESMF_FieldBundleAdd(nst_bundle, (/c_d_target_grid,c_0_target_grid,d_conv_target_grid, & + dt_cool_target_grid,ifd_target_grid,qrain_target_grid,& + w_d_target_grid,w_0_target_grid,xs_target_grid,xt_target_grid,& + xu_target_grid,xv_target_grid,xtts_target_grid,xzts_target_grid, & + z_c_target_grid, zm_target_grid/), rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldBundleAdd", rc) + + do i = 1,16 + call ESMF_FieldBundleGet(nst_bundle,i,tmp_field,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldBundleGet", rc) + call ESMF_FieldGet(tmp_field,farrayPtr=tmp_ptr,rc=rc) + tmp_ptr(:,:) = init_val + enddo + call ESMF_FieldGet(tref_target_grid,farrayPtr=tmp_ptr,rc=rc) + tmp_ptr(:,:) = init_val + call ESMF_FieldGet(xz_target_grid,farrayPtr=tmp_ptr,rc=rc) + tmp_ptr(:,:) = init_val + + !Call the routine to unit test. + call nst_land_fill + + allocate(tmp_array_2d(i_target,j_target)) + + print*,"Check results." + do i = 1, 16 + call ESMF_FieldBundleGet(nst_bundle,i,tmp_field,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldBundleGet", rc) + call ESMF_FieldGather(tmp_field,tmp_array_2d,rootPet=0,tile=1,rc=rc) + call ESMF_FieldGet(tmp_field,name=fname,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldGet", rc) + + if (any((abs(tmp_array_2d - nst_field_correct)) > EPSILON)) then + print*,'TEST FAILED ' + print*,'ARRAY ', trim(fname), ' SHOULD BE:', nst_field_correct + print*,'ARRAY ', trim(fname), ' FROM TEST:', tmp_array_2d + stop 2 + endif + enddo + call ESMF_FieldBundleDestroy(nst_bundle,rc=rc) + + call ESMF_FieldGather(tref_target_grid,tmp_array_2d,rootPet=0,tile=1,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldGater", rc) + + if (any((abs(tmp_array_2d - tref_correct)) > EPSILON)) then + print*,'TEST FAILED ' + print*,'TREF SHOULD BE:', tref_correct + print*,'TREF FROM TEST:', tmp_array_2d + stop 2 + endif + + call ESMF_FieldGather(xz_target_grid,tmp_array_2d,rootPet=0,tile=1,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldGater", rc) + + if (any((abs(tmp_array_2d - xz_correct)) > EPSILON)) then + print*,'TEST FAILED ' + print*,'XZ SHOULD BE:', xz_correct + print*,'XZ FROM TEST:', tmp_array_2d + stop 2 + endif + + + print*,"OK" + + deallocate(tmp_array_2d,nst_field_correct,tref_correct,xz_correct) + + call ESMF_FieldDestroy(landmask_target_grid,rc=rc) + call ESMF_FieldDestroy(skin_temp_target_grid,rc=rc) + call cleanup_target_nst_data + call ESMF_GridDestroy(target_grid,rc=rc) + call ESMF_finalize(endflag=ESMF_END_KEEPMPI) + call mpi_finalize(rc) + + print*,"SUCCESS!" + + end program surface_nst_landfill