From 4fdee55ae2d844e1dff968f4df4fb19197455822 Mon Sep 17 00:00:00 2001 From: GeorgeGayno-NOAA <52789452+GeorgeGayno-NOAA@users.noreply.github.com> Date: Tue, 22 Mar 2022 13:49:54 -0400 Subject: [PATCH] chgres_cube - Remove the wgrib2 library from the GRIB2 data read routines. Update routines "read_input_atm_grib2_file", "read_input_sfc_grib2_file", "read_winds" and "read_grib_soil" to read input GRIB2 files using G2LIB instead of WGRIB2. Update routine "define_input_grid_gfs_grib2" to flip the pole of GFS GRIB2 data. WGRIB2 and G2LIB use different conventions for defining global gaussian grids. Update to G2LIB v3.4.3 or higher, which eliminated occasional segmentation faults and slow wall clock times. Add new units test for GRIB2 read routines "read_input_atm_grib2_file" and "read_input_sfc_grib2_file". Part of #591. --- CMakeLists.txt | 2 +- modulefiles/build.hera.gnu.lua | 2 +- modulefiles/build.hera.intel.lua | 2 +- modulefiles/build.jet.intel.lua | 2 +- modulefiles/build.orion.intel.lua | 2 +- modulefiles/build.wcoss_cray.intel | 5 +- modulefiles/build.wcoss_dell_p3.intel.lua | 2 +- reg_tests/chgres_cube/driver.wcoss_dell_p3.sh | 4 +- sorc/chgres_cube.fd/CMakeLists.txt | 1 + sorc/chgres_cube.fd/input_data.F90 | 2575 +++++++++++------ sorc/chgres_cube.fd/model_grid.F90 | 10 +- tests/chgres_cube/CMakeLists.txt | 12 + tests/chgres_cube/LSanSuppress.supp | 1 + tests/chgres_cube/data/files.txt | 1 + tests/chgres_cube/ftst_read_atm_grib2.F90 | 256 ++ tests/chgres_cube/ftst_read_sfc_grib2.F90 | 352 +++ tests/chgres_cube/ftst_sfc_input_data.F90 | 2 +- ush/chgres_cube.sh | 4 +- 18 files changed, 2277 insertions(+), 958 deletions(-) create mode 100644 tests/chgres_cube/ftst_read_atm_grib2.F90 create mode 100644 tests/chgres_cube/ftst_read_sfc_grib2.F90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 519a17200..38bcfb5ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ find_package(nemsio 2.5.0 REQUIRED) find_package(sigio 2.3.0 REQUIRED) find_package(sp 2.3.3 REQUIRED) find_package(ip 3.3.3 REQUIRED) -find_package(g2 3.4.0 REQUIRED) +find_package(g2 3.4.3 REQUIRED) find_package(wgrib2 2.0.8 REQUIRED) find_package(sigio 2.3.0 REQUIRED) diff --git a/modulefiles/build.hera.gnu.lua b/modulefiles/build.hera.gnu.lua index 88aa5ef57..90bca87ae 100644 --- a/modulefiles/build.hera.gnu.lua +++ b/modulefiles/build.hera.gnu.lua @@ -28,7 +28,7 @@ load(pathJoin("esmf", esmf_ver)) bacio_ver=os.getenv("bacio_ver") or "2.4.1" load(pathJoin("bacio", bacio_ver)) -g2_ver=os.getenv("g2_ver") or "3.4.1" +g2_ver=os.getenv("g2_ver") or "3.4.3" load(pathJoin("g2", g2_ver)) ip_ver=os.getenv("ip_ver") or "3.3.3" diff --git a/modulefiles/build.hera.intel.lua b/modulefiles/build.hera.intel.lua index 319d7b3ed..48335e748 100644 --- a/modulefiles/build.hera.intel.lua +++ b/modulefiles/build.hera.intel.lua @@ -22,7 +22,7 @@ load(pathJoin("hpc-impi", impi_ver)) bacio_ver=os.getenv("bacio_ver") or "2.4.1" load(pathJoin("bacio", bacio_ver)) -g2_ver=os.getenv("g2_ver") or "3.4.1" +g2_ver=os.getenv("g2_ver") or "3.4.3" load(pathJoin("g2", g2_ver)) ip_ver=os.getenv("ip_ver") or "3.3.3" diff --git a/modulefiles/build.jet.intel.lua b/modulefiles/build.jet.intel.lua index 260fda2cc..50f23bb96 100644 --- a/modulefiles/build.jet.intel.lua +++ b/modulefiles/build.jet.intel.lua @@ -52,7 +52,7 @@ load(pathJoin("sfcio", sfcio_ver)) nemsio_ver=os.getenv("nemsio_ver") or "2.5.2" load(pathJoin("nemsio", nemsio_ver)) -g2_ver=os.getenv("g2_ver") or "3.4.1" +g2_ver=os.getenv("g2_ver") or "3.4.3" load(pathJoin("g2", g2_ver)) wgrib2_ver=os.getenv("wgrib2_ver") or "2.0.8" diff --git a/modulefiles/build.orion.intel.lua b/modulefiles/build.orion.intel.lua index 0fabb4ebc..d641cdaf5 100644 --- a/modulefiles/build.orion.intel.lua +++ b/modulefiles/build.orion.intel.lua @@ -19,7 +19,7 @@ load(pathJoin("hpc-impi", impi_ver)) bacio_ver=os.getenv("bacio_ver") or "2.4.1" load(pathJoin("bacio", bacio_ver)) -g2_ver=os.getenv("g2_ver") or "3.4.1" +g2_ver=os.getenv("g2_ver") or "3.4.3" load(pathJoin("g2", g2_ver)) ip_ver=os.getenv("ip_ver") or "3.3.3" diff --git a/modulefiles/build.wcoss_cray.intel b/modulefiles/build.wcoss_cray.intel index 5be5083b3..7ae0c107f 100644 --- a/modulefiles/build.wcoss_cray.intel +++ b/modulefiles/build.wcoss_cray.intel @@ -18,7 +18,6 @@ module load cray-hdf5/1.8.14 module use /usrx/local/nceplibs/NCEPLIBS/cmake/install/NCEPLIBS-v1.3.0/modules module load bacio/2.4.1 -module load g2/3.4.1 module load ip/3.3.3 module load nemsio/2.5.2 module load sp/2.3.3 @@ -31,7 +30,11 @@ setenv ZLIB_ROOT /usrx/local/prod/zlib/1.2.7/intel/haswell setenv PNG_ROOT /usrx/local/prod/png/1.2.49/intel/haswell setenv Jasper_ROOT /usrx/local/prod/jasper/1.900.1/intel/haswell +module use /usrx/local/nceplibs/NCEPLIBS/cmake/install/NCEPLIBS-v1.4.0/modules +module load g2/3.4.5 + module load esmf/820 + setenv NETCDF /opt/cray/netcdf/4.3.3.1/INTEL/14.0 module rm gcc module load gcc/6.3.0 diff --git a/modulefiles/build.wcoss_dell_p3.intel.lua b/modulefiles/build.wcoss_dell_p3.intel.lua index 427692697..0c0f3955e 100644 --- a/modulefiles/build.wcoss_dell_p3.intel.lua +++ b/modulefiles/build.wcoss_dell_p3.intel.lua @@ -43,7 +43,7 @@ load(pathJoin("esmf", esmf_ver)) bacio_ver=os.getenv("bacio_ver") or "2.4.1" load(pathJoin("bacio", bacio_ver)) -g2_ver=os.getenv("g2_ver") or "3.4.2" +g2_ver=os.getenv("g2_ver") or "3.4.5" load(pathJoin("g2", g2_ver)) ip_ver=os.getenv("ip_ver") or "3.3.3" diff --git a/reg_tests/chgres_cube/driver.wcoss_dell_p3.sh b/reg_tests/chgres_cube/driver.wcoss_dell_p3.sh index 04ab66c72..6f4e8e821 100755 --- a/reg_tests/chgres_cube/driver.wcoss_dell_p3.sh +++ b/reg_tests/chgres_cube/driver.wcoss_dell_p3.sh @@ -76,7 +76,7 @@ bsub -e $LOG_FILE -o $LOG_FILE -q $QUEUE -P $PROJECT_CODE -J chgres01 -W 0:05 -x LOG_FILE=consistency.log02 export OMP_NUM_THREADS=1 -bsub -e $LOG_FILE -o $LOG_FILE -q $QUEUE -P $PROJECT_CODE -J chgres02 -W 0:07 -x -n 6 \ +bsub -e $LOG_FILE -o $LOG_FILE -q $QUEUE -P $PROJECT_CODE -J chgres02 -W 0:10 -x -n 6 \ -R "span[ptile=6]" -R "affinity[core(${OMP_NUM_THREADS}):distribute=balance]" "$PWD/3km.conus.hrrr.gfssdf.grib2.sh" #----------------------------------------------------------------------------- @@ -103,7 +103,7 @@ bsub -e $LOG_FILE -o $LOG_FILE -q $QUEUE -P $PROJECT_CODE -J chgres04 -W 0:05 -x LOG_FILE=consistency.log05 export OMP_NUM_THREADS=1 -bsub -e $LOG_FILE -o $LOG_FILE -q $QUEUE -P $PROJECT_CODE -J chgres05 -W 0:05 -x -n 6 \ +bsub -e $LOG_FILE -o $LOG_FILE -q $QUEUE -P $PROJECT_CODE -J chgres05 -W 0:10 -x -n 6 \ -R "span[ptile=6]" -R "affinity[core(${OMP_NUM_THREADS}):distribute=balance]" "$PWD/13km.conus.rap.grib2.sh" #----------------------------------------------------------------------------- diff --git a/sorc/chgres_cube.fd/CMakeLists.txt b/sorc/chgres_cube.fd/CMakeLists.txt index 7b6ad9388..c148cfb8c 100644 --- a/sorc/chgres_cube.fd/CMakeLists.txt +++ b/sorc/chgres_cube.fd/CMakeLists.txt @@ -42,6 +42,7 @@ target_include_directories(chgres_cube_lib INTERFACE ${mod_dir}) target_link_libraries( chgres_cube_lib PUBLIC + g2::g2_d nemsio::nemsio sfcio::sfcio sigio::sigio diff --git a/sorc/chgres_cube.fd/input_data.F90 b/sorc/chgres_cube.fd/input_data.F90 index 965c37df1..420b92955 100644 --- a/sorc/chgres_cube.fd/input_data.F90 +++ b/sorc/chgres_cube.fd/input_data.F90 @@ -384,8 +384,6 @@ subroutine read_input_sfc_data(localpet) integer, intent(in) :: localpet - integer :: rc - call init_sfc_esmf_fields() !------------------------------------------------------------------------------- @@ -2458,7 +2456,7 @@ end subroutine read_input_atm_tiled_history_file subroutine read_input_atm_grib2_file(localpet) use mpi - use wgrib2api + use grib_mod use grib2_util, only : rh2spfh, rh2spfh_gfs, convert_omega @@ -2467,34 +2465,39 @@ subroutine read_input_atm_grib2_file(localpet) integer, intent(in) :: localpet integer, parameter :: ntrac_max=14 + integer, parameter :: max_levs=1000 character(len=300) :: the_file - character(len=20) :: vlevtyp, vname, lvl_str,lvl_str_space, & - trac_names_grib_1(ntrac_max), & - trac_names_grib_2(ntrac_max), & + character(len=20) :: vname, & trac_names_vmap(ntrac_max), & - tracers_input_grib_1(num_tracers_input), & - tracers_input_grib_2(num_tracers_input), & tmpstr, & method, tracers_input_vmap(num_tracers_input), & - tracers_default(ntrac_max), vname2 - character (len=500) :: metadata + tracers_default(ntrac_max) - integer :: i, j, k, n, lvl_str_space_len + integer :: i, j, k, n integer :: ii,jj integer :: rc, clb(3), cub(3) - integer :: vlev, iret,varnum - integer :: all_empty, o3n - integer :: len_str - integer :: is_missing, intrp_ier, done_print + integer :: vlev, iret,varnum, o3n + integer :: intrp_ier, done_print + integer :: trac_names_oct10(ntrac_max) + integer :: tracers_input_oct10(num_tracers_input) + integer :: trac_names_oct11(ntrac_max) + integer :: tracers_input_oct11(num_tracers_input) + integer :: lugb, lugi, jdisc, jpdt(200), jgdt(200), iscale + integer :: jids(200), jpdtn, jgdtn, octet23, octet29 + integer :: count_spfh, count_rh, count_icmr, count_scliwc + integer :: count_cice, count_rwmr, count_scllwc, count - logical :: lret logical :: conv_omega=.false., & hasspfh=.true., & isnative=.false., & - use_rh=.false. + use_rh=.false. , unpack, & + all_empty, is_missing + + real(esmf_kind_r8), allocatable :: dum2d_1(:,:) + real(esmf_kind_r8) :: rlevs_hold(max_levs) real(esmf_kind_r8), allocatable :: rlevs(:) real(esmf_kind_r4), allocatable :: dummy2d(:,:) real(esmf_kind_r8), allocatable :: dummy3d(:,:,:), dummy2d_8(:,:),& @@ -2509,20 +2512,18 @@ subroutine read_input_atm_grib2_file(localpet) real(esmf_kind_r4), parameter :: lev_no_tr_fill = 20000.0 real(esmf_kind_r4), parameter :: lev_no_o3_fill = 40000.0 + type(gribfield) :: gfld tracers(:) = "NULL" - !trac_names_grib = (/":SPFH:",":CLWR:", "O3MR",":CICE:", ":RWMR:",":SNMR:",":GRLE:", & - ! ":TCDC:", ":NCCICE:",":SPNCR:", ":NCONCD:",":PMTF:",":PMTC:",":TKE:"/) - trac_names_grib_1 = (/":var0_2", ":var0_2", ":var0_2", ":var0_2", ":var0_2",":var0_2", \ - ":var0_2", ":var0_2", ":var0_2", ":var0_2", ":var0_2",":var0_2", \ - ":var0_2", ":var0_2"/) - trac_names_grib_2 = (/"_1_0: ", "_1_22: ", "_14_192:", "_1_23: ", "_1_24: ","_1_25: ", \ - "_1_32: ", "_6_1: ", "_6_29: ", "_1_100: ", "_6_28: ","_13_193:", \ - "_13_192:", "_2_2: "/) + + trac_names_oct10 = (/1, 1, 14, 1, 1, 1, 1, 6, 6, 1, 6, 13, 13, 2 /) + trac_names_oct11 = (/0, 22, 192, 23, 24, 25, 32, 1, 29, 100, 28, 193, 192, 2 /) + trac_names_vmap = (/"sphum ", "liq_wat ", "o3mr ", "ice_wat ", & "rainwat ", "snowwat ", "graupel ", "cld_amt ", "ice_nc ", & "rain_nc ", "water_nc", "liq_aero", "ice_aero", & "sgs_tke "/) + tracers_default = (/"sphum ", "liq_wat ", "o3mr ", "ice_wat ", & "rainwat ", "snowwat ", "graupel ", "cld_amt ", "ice_nc ", & "rain_nc ", "water_nc", "liq_aero", "ice_aero", & @@ -2531,153 +2532,294 @@ subroutine read_input_atm_grib2_file(localpet) the_file = trim(data_dir_input_grid) // "/" // trim(grib2_file_input_grid) print*,"- READ ATMOS DATA FROM GRIB2 FILE: ", trim(the_file) - print*,"- USE INVENTORY FILE ", inv_file - print*,"- OPEN FILE." - inquire(file=the_file,exist=lret) - if (.not.lret) call error_handler("OPENING GRIB2 ATM FILE.", iret) + if (localpet == 0) then + + lugb=14 + lugi=0 + call baopenr(lugb,the_file,iret) + if (iret /= 0) call error_handler("ERROR OPENING GRIB2 FILE.", iret) + + jdisc = 0 ! Search for discipline - meteorological products + j = 0 ! Search at beginning of file. + jpdt = -9999 ! Array of values in product definition template, set to wildcard + jids = -9999 ! Array of values in identification section, set to wildcard + jgdt = -9999 ! Array of values in grid definition template, set to wildcard + jgdtn = -1 ! Search for any grid definition number. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + +! First, check for the vertical coordinate. If temperture at the 10 hybrid +! level is found, hybrid coordinates are assumed. Otherwise, data is on +! isobaric levels. + + jpdt(1) = 0 ! Sect4/oct 10 - param category - temperature field + jpdt(2) = 0 ! Sect4/oct 11 - param number - temperature + jpdt(10) = 105 ! Sect4/oct 23 - type of level - hybrid + jpdt(12) = 10 ! oct 23 - type of level - value of hybrid level + unpack=.false. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret == 0) then ! data is on hybrid levels + octet23 = 105 + octet29 = 255 + isnative=.true. + else ! data is on isobaric levels + octet23 = 100 + octet29 = 255 + endif + +! Now count the number of vertical levels by searching for u-wind. +! Store the value of each level. + + rlevs_hold = -999.9 + lev_input = 0 + iret = 0 + j = 0 + jpdt = -9999 + + do + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret /= 0) exit + + if (gfld%discipline == 0) then ! Discipline - meteorological products + if (gfld%ipdtnum == 0) then ! Product definition template number - + ! analysis or forecast at single level. + if (gfld%ipdtmpl(1) == 2 .and. gfld%ipdtmpl(2) == 2) then ! u-wind + ! Sect4/octs 10 and 11. + if (gfld%ipdtmpl(10) == octet23 .and. gfld%ipdtmpl(13) == octet29) then + ! Sect4 octs 23 and 29. + ! Hybrid or isobaric. + lev_input = lev_input + 1 + iscale = 10 ** gfld%ipdtmpl(11) + rlevs_hold(lev_input) = float(gfld%ipdtmpl(12))/float(iscale) + endif + endif + endif + endif + + j = k + enddo - print*,"- READ VERTICAL COORDINATE." - iret = grb2_inq(the_file,inv_file,":var0_2","_0_0:",":10 hybrid level:") - - if (iret <= 0) then - lvl_str = "mb:" - lvl_str_space = " mb:" - lvl_str_space_len = 4 - isnative = .false. - iret = grb2_inq(the_file,inv_file,":UGRD:",lvl_str_space) - lev_input=iret - if (localpet == 0) print*,"- DATA IS ON ", lev_input, " ISOBARIC LEVELS." - else - lvl_str = " level:" - lvl_str_space = " hybrid " - lvl_str_space_len = 7 - isnative = .true. - iret = grb2_inq(the_file,inv_file,":UGRD:",lvl_str_space, " level:") - if (iret < 0) call error_handler("READING VERTICAL LEVEL TYPE.", iret) - lev_input=iret endif + call mpi_barrier(MPI_COMM_WORLD, iret) + call MPI_BCAST(isnative,1,MPI_LOGICAL,0,MPI_COMM_WORLD,iret) + call MPI_BCAST(lev_input,1,MPI_INTEGER,0,MPI_COMM_WORLD,iret) + call MPI_BCAST(rlevs_hold, max_levs, MPI_INTEGER,0,MPI_COMM_WORLD,iret) + allocate(slevs(lev_input)) allocate(rlevs(lev_input)) allocate(dummy3d_col_in(lev_input)) allocate(dummy3d_col_out(lev_input)) levp1_input = lev_input + 1 - -! Get the vertical levels, and search string by sequential reads - - do i = 1,lev_input - iret=grb2_inq(the_file,inv_file,':UGRD:',trim(lvl_str),sequential=i-1,desc=metadata) - if (iret.ne.1) call error_handler(" IN SEQUENTIAL FILE READ.", iret) - - j = index(metadata,':UGRD:') + len(':UGRD:') - k = index(metadata,trim(lvl_str_space)) + len(trim(lvl_str_space))-1 - read(metadata(j:k),*) rlevs(i) +! Jili Dong add sort to re-order isobaric levels. - slevs(i) = metadata(j-1:k) - if (.not. isnative) rlevs(i) = rlevs(i) * 100.0 - if (localpet==0) print*, "- LEVEL = ", slevs(i) + do i = 1, lev_input + rlevs(i) = rlevs_hold(i) enddo -! Jili Dong add sort to re-order isobaric levels. - call quicksort(rlevs,1,lev_input) - if (.not. isnative) then + do i = 1, lev_input + if (isnative) then + write(slevs(i), '(i6)') nint(rlevs(i)) + slevs(i) = trim(slevs(i)) // " hybrid" + else + write(slevs(i), '(f11.2)') rlevs(i) + slevs(i) = trim(slevs(i)) // " Pa" + endif + enddo + + if(localpet == 0) then do i = 1,lev_input - write(slevs(i),"(F20.10)") rlevs(i)/100.0 - len_str = len_trim(slevs(i)) + print*, "- LEVEL AFTER SORT = ",trim(slevs(i)) + enddo + endif - do while (slevs(i)(len_str:len_str) .eq. '0') - slevs(i) = slevs(i)(:len_str-1) - len_str = len_str - 1 - end do +! Check to see if specfic humidity exists at all the same levels as ugrd. + + if (localpet == 0) then + + jpdt = -9999 + jpdt(1) = 1 ! Sect4/oct 10 - param category - moisture + jpdt(2) = 0 ! Sect4/oct 11 - param number - specific humidity + if (isnative) then + jpdt(10) = 105 ! Sect4/oct 23 - type of level - hybrid + else + jpdt(10) = 100 ! Sect4/oct 23 - type of level - isobaric + endif + unpack=.false. + + count_spfh=0 - if (slevs(i)(len_str:len_str) .eq. '.') then - slevs(i) = slevs(i)(:len_str-1) - len_str = len_str - 1 - end if + do vlev = 1, lev_input + j = 0 + jpdt(12) = nint(rlevs(vlev)) + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) - slevs(i) = trim(slevs(i)) + if (iret == 0) then + count_spfh = count_spfh + 1 + endif - slevs(i) = ":"//trim(adjustl(slevs(i)))//" mb:" - if (localpet==0) print*, "- LEVEL AFTER SORT = ",slevs(i) enddo - endif -! Is SPFH on full levels Jili Dong - do vlev = 1, lev_input - iret = grb2_inq(the_file,inv_file,':SPFH:',slevs(vlev)) - if (iret <= 0) then - use_rh = .TRUE. - if (localpet == 0) print*, ':SPFH on level '//trim(slevs(vlev))//' does not exist. & - Will read in RH and convert to SPFH instead.' - exit - end if - end do + jpdt(1) = 1 ! Sec4/oct 10 - param category - moisture + jpdt(2) = 1 ! Sec4/oct 11 - param number - rel humidity + count_rh=0 - - if (localpet == 0) print*,"- FIND SPFH OR RH IN FILE" - iret = grb2_inq(the_file,inv_file,trim(trac_names_grib_1(1)),trac_names_grib_2(1),lvl_str_space) - - if (iret <= 0 .or. use_rh) then - iret = grb2_inq(the_file,inv_file, ':var0_2','_1_1:',lvl_str_space) - if (iret <= 0) call error_handler("READING ATMOSPHERIC WATER VAPOR VARIABLE.", iret) - hasspfh = .false. - trac_names_grib_2(1)='_1_1:' - if (localpet == 0) print*,"- FILE CONTAINS RH." - else - if (localpet == 0) print*,"- FILE CONTAINS SPFH." - endif - - if (localpet == 0) print*,"- FIND ICMR, SCLIWC, OR CICE IN FILE" - iret = grb2_inq(the_file,inv_file,trac_names_grib_1(4),trac_names_grib_2(4),lvl_str_space) + do vlev = 1, lev_input + j = 0 + jpdt(12) = nint(rlevs(vlev)) - if (iret <= 0) then - vname = trac_names_vmap(4) - print*, "vname = ", vname - call get_var_cond(vname,this_miss_var_method=method, this_miss_var_value=value, & - this_field_var_name=tmpstr,loc=varnum) - iret = grb2_inq(the_file,inv_file, ':var0_2','_1_84:',lvl_str_space) - if (iret <= 0) then - iret = grb2_inq(the_file,inv_file, ':var0_2','_6_0:',lvl_str_space) - if (iret <= 0 ) then - call handle_grib_error(vname, slevs(1),method,value,varnum,rc,var=dummy2d) - else - trac_names_grib_2(4) = '_6_0' - if (localpet == 0) print*,"- FILE CONTAINS CICE." - endif + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret == 0) then + count_rh = count_rh + 1 + endif + enddo + + if (count_spfh /= lev_input) then + use_rh = .true. + endif + + if (count_spfh == 0 .or. use_rh) then + if (count_rh == 0) then + call error_handler("READING ATMOSPHERIC WATER VAPOR VARIABLE.", 2) + endif + hasspfh = .false. ! Will read rh and convert to specific humidity. + trac_names_oct10(1) = 1 + trac_names_oct11(1) = 1 + print*,"- FILE CONTAINS RH." else - trac_names_grib_2(4)='_1_84:' - if (localpet == 0) print*,"- FILE CONTAINS SCLIWC." + print*,"- FILE CONTAINS SPFH." endif - else - if (localpet == 0) print*,"- FILE CONTAINS ICMR." + endif + + call MPI_BARRIER(MPI_COMM_WORLD, rc) + call MPI_BCAST(hasspfh,1,MPI_LOGICAL,0,MPI_COMM_WORLD,rc) - if (localpet == 0) print*,"- FIND CLWMR or SCLLWC IN FILE" - iret = grb2_inq(the_file,inv_file,trac_names_grib_1(5),trac_names_grib_2(5),lvl_str_space) +! Search for and count the number of tracers in the file. - if (iret <= 0) then - vname = trac_names_vmap(5) - print*, "vname = ", vname - call get_var_cond(vname,this_miss_var_method=method, this_miss_var_value=value, & - this_field_var_name=tmpstr,loc=varnum) - iret = grb2_inq(the_file,inv_file, ':var0_2','_1_83:',lvl_str_space) - if (iret <= 0) then - call handle_grib_error(vname, slevs(1),method,value,varnum,rc,var=dummy2d) - elseif (iret <=0 .and. rc .ne. 1) then - call error_handler("READING CLOUD WATER VARIABLE.", iret) + if (localpet == 0) then + + jpdt = -9999 + if (isnative) then + jpdt(10) = 105 ! Sect4/oct 23 - type of level - hybrid else - trac_names_grib_2(4)='_1_83:' - if (localpet == 0) print*,"- FILE CONTAINS SCLLWC." + jpdt(10) = 100 ! Sect4/oct 23 - type of level - isobaric endif - else - if (localpet == 0) print*,"- FILE CONTAINS CLWMR." - endif + unpack=.false. + + count_icmr=0 + count_scliwc=0 + count_cice=0 + count_rwmr=0 + count_scllwc=0 + + do vlev = 1, lev_input + + j = 0 + jpdt(1) = 1 ! Sect4/oct 10 - param category - moisture + jpdt(2) = 23 ! Sect4/oct 11 - param number - ice water mixing ratio + jpdt(12) = nint(rlevs(vlev)) + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret == 0) then + count_icmr = count_icmr + 1 + endif + + j = 0 + jpdt(1) = 1 ! Sect4/oct 10 - param category - moisture + jpdt(2) = 84 ! Sect4/oct 11 - param number - cloud ice water content. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret == 0) then + count_scliwc = count_scliwc + 1 + endif + + j = 0 + jpdt(1) = 6 ! Sect4/oct 10 - param category - clouds + jpdt(2) = 0 ! Sect4/oct 11 - param number - cloud ice + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret == 0) then + count_cice = count_cice + 1 + endif + + j = 0 + jpdt(1) = 1 ! Sect4/oct 10 - param category - moisture + jpdt(2) = 24 ! Sect4/oct 11 - param number - rain mixing ratio + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret == 0) then + count_rwmr = count_rwmr + 1 + endif + + j = 0 + jpdt(1) = 1 ! Sect4/oct 10 - param category - moisture + jpdt(2) = 83 ! Sect4/oct 11 - param number - specific cloud liquid + ! water content. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret == 0) then + count_scllwc = count_scllwc + 1 + endif + + enddo + + if (count_icmr == 0) then + if (count_scliwc == 0) then + if (count_cice == 0) then + print*,'- FILE DOES NOT CONTAIN CICE.' + else + trac_names_oct10(4) = 6 ! Sect4/oct 10 - param category - clouds + trac_names_oct11(4) = 0 ! Sect4/oct 11 - param number - cloud ice + print*,"- FILE CONTAINS CICE." + endif + else + trac_names_oct10(4) = 1 ! Sect4/oct 10 - param category - moisture + trac_names_oct11(4) = 84 ! Sect4/oct 11 - param number - cloud ice water content. + print*,"- FILE CONTAINS SCLIWC." + endif + else + print*,"- FILE CONTAINS ICMR." + endif ! count of icmr + + if (count_rwmr == 0) then + if (count_scllwc == 0) then + print*,"- FILE DOES NOT CONTAIN SCLLWC." + else + trac_names_oct10(4) = 1 ! Sect4/oct 10 - param category - moisture + trac_names_oct11(4) = 83 ! Sect4/oct 11 - param number - specific cloud liquid + ! water content. + print*,"- FILE CONTAINS SCLLWC." + endif + else + print*,"- FILE CONTAINS CLWMR." + endif + + endif ! count of tracers/localpet = 0 + call MPI_BARRIER(MPI_COMM_WORLD, rc) + call MPI_BCAST(trac_names_oct10,ntrac_max,MPI_INTEGER,0,MPI_COMM_WORLD,rc) + call MPI_BCAST(trac_names_oct11,ntrac_max,MPI_INTEGER,0,MPI_COMM_WORLD,rc) + print*,"- COUNT NUMBER OF TRACERS TO BE READ IN BASED ON PHYSICS SUITE TABLE" do n = 1, num_tracers_input @@ -2685,17 +2827,14 @@ subroutine read_input_atm_grib2_file(localpet) i = maxloc(merge(1.,0.,trac_names_vmap == vname),dim=1) - tracers_input_grib_1(n) = trac_names_grib_1(i) - tracers_input_grib_2(n) = trac_names_grib_2(i) tracers_input_vmap(n)=trac_names_vmap(i) tracers(n)=tracers_default(i) if(trim(tracers(n)) .eq. "o3mr") o3n = n - enddo + tracers_input_oct10(n) = trac_names_oct10(i) + tracers_input_oct11(n) = trac_names_oct11(i) - if (localpet==0) then - print*, "- NUMBER OF TRACERS IN THE INPUT FILE = ", num_tracers_input - endif + enddo !--------------------------------------------------------------------------- ! Initialize esmf atmospheric fields. @@ -2707,10 +2846,12 @@ subroutine read_input_atm_grib2_file(localpet) allocate(dummy2d(i_input,j_input)) allocate(dummy2d_8(i_input,j_input)) allocate(dummy3d(i_input,j_input,lev_input)) + allocate(dum2d_1(i_input,j_input)) else allocate(dummy2d(0,0)) allocate(dummy2d_8(0,0)) allocate(dummy3d(0,0,0)) + allocate(dum2d_1(0,0)) endif !---------------------------------------------------------------------------------- @@ -2720,98 +2861,171 @@ subroutine read_input_atm_grib2_file(localpet) !---------------------------------------------------------------------------------- if (localpet == 0) then + print*,"- READ TEMPERATURE." - vname = ":TMP:" - do vlev = 1, lev_input - iret = grb2_inq(the_file,inv_file,vname,slevs(vlev),data2=dummy2d) - if (iret<=0) then - call error_handler("READING IN TEMPERATURE AT LEVEL "//trim(slevs(vlev)),iret) - endif - dummy3d(:,:,vlev) = real(dummy2d,esmf_kind_r8) - print*,'temp check after read ',vlev, dummy3d(1,1,vlev) - enddo - endif + + jdisc = 0 ! search for discipline - meteorological products + j = 0 ! search at beginning of file. + jpdt = -9999 ! array of values in product definition template, set to wildcard + jids = -9999 ! array of values in identification section, set to wildcard + jgdt = -9999 ! array of values in grid definition template, set to wildcard + jgdtn = -1 ! search for any grid definition number. + jpdtn = 0 ! search for product def template number 0 - anl or fcst. + jpdt(1) = 0 ! Sect 4/oct 10 - param category - temperature + jpdt(2) = 0 ! Sect 4/oct 11 - param number - temperature + + if (isnative) then + jpdt(10) = 105 ! Sect 4/oct 23 - type of level - hybrid + else + jpdt(10) = 100 ! Sect 4/oct 23 - type of level - isobaric + endif + + unpack=.true. + + do vlev = 1, lev_input + + jpdt(12) = nint(rlevs(vlev)) + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + if (iret /= 0) then + call error_handler("READING IN TEMPERATURE AT LEVEL "//trim(slevs(vlev)),iret) + endif + + dum2d_1 = reshape(gfld%fld, (/i_input,j_input/) ) + + dummy3d(:,:,vlev) = dum2d_1 + + enddo + + endif ! Read of temperature if (localpet == 0) print*,"- CALL FieldScatter FOR INPUT GRID TEMPERATURE." call ESMF_FieldScatter(temp_input_grid, dummy3d, rootpet=0, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldScatter", rc) +! Read tracers + do n = 1, num_tracers_input if (localpet == 0) print*,"- READ ", trim(tracers_input_vmap(n)) + vname = tracers_input_vmap(n) call get_var_cond(vname,this_miss_var_method=method, this_miss_var_value=value, & this_field_var_name=tmpstr,loc=varnum) + if (n==1 .and. .not. hasspfh) then - print*,"- CALL FieldGather TEMPERATURE." - call ESMF_FieldGather(temp_input_grid,dummy3d,rootPet=0, tile=1, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGet", rc) + print*,"- CALL FieldGather TEMPERATURE." + call ESMF_FieldGather(temp_input_grid,dummy3d,rootPet=0, tile=1, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & + call error_handler("IN FieldGet", rc) endif if (localpet == 0) then - vname = trim(tracers_input_grib_1(n)) - vname2 = trim(tracers_input_grib_2(n)) - iret = grb2_inq(the_file,inv_file,vname,lvl_str_space,vname2) + + jdisc = 0 ! search for discipline - meteorological products + jpdt = -9999 ! array of values in product definition template, set to wildcard + jids = -9999 ! array of values in identification section, set to wildcard + jgdt = -9999 ! array of values in grid definition template, set to wildcard + jgdtn = -1 ! search for any grid definition number. + jpdtn = 0 ! search for product def template number 0 - anl or fcst. + unpack = .false. + if (isnative) then + jpdt(10) = 105 ! Sect4/oct 23 - type of level - hybrid + else + jpdt(10) = 100 ! Sect4/oct 23 - type of level - isobaric + endif + + count = 0 + + do vlev = 1, lev_input + + j = 0 + jpdt(1) = tracers_input_oct10(n) + jpdt(2) = tracers_input_oct11(n) + jpdt(12) = nint(rlevs(vlev)) + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret == 0) then + count = count + 1 + endif + + enddo + iret=count ! Check to see if file has any data for this tracer if (iret == 0) then - all_empty = 1 + all_empty = .true. else - all_empty = 0 + all_empty = .false. endif - is_missing = 0 + is_missing = .false. + do vlev = 1, lev_input - iret = grb2_inq(the_file,inv_file,vname,slevs(vlev),vname2,data2=dummy2d) - - if (iret <= 0) then - if (trim(method) .eq. 'intrp' .and. all_empty == 0) then + + unpack=.true. + j = 0 + jpdt(1) = tracers_input_oct10(n) + jpdt(2) = tracers_input_oct11(n) + jpdt(12) = nint(rlevs(vlev) ) + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret == 0) then ! found data + dummy2d = reshape(gfld%fld, (/i_input,j_input/) ) + else ! did not find data. + if (trim(method) .eq. 'intrp' .and. .not.all_empty) then dummy2d = intrp_missing - is_missing = 1 + is_missing = .true. else ! Abort if input data has some data for current tracer, but has ! missing data below 200 mb/ above 400mb - if (all_empty == 0 .and. n == o3n) then + if (.not.all_empty .and. n == o3n) then if (rlevs(vlev) .lt. lev_no_o3_fill) & call error_handler("TRACER "//trim(tracers(n))//" HAS MISSING DATA AT "//trim(slevs(vlev))//& ". SET MISSING VARIABLE CONDITION TO 'INTRP' TO AVOID THIS ERROR", 1) - elseif (all_empty == 0 .and. n .ne. o3n) then + elseif (.not.all_empty .and. n .ne. o3n) then if (rlevs(vlev) .gt. lev_no_tr_fill) & call error_handler("TRACER "//trim(tracers(n))//" HAS MISSING DATA AT "//trim(slevs(vlev))//& ". SET MISSING VARIABLE CONDITION TO 'INTRP' TO AVOID THIS ERROR.", 1) endif ! If entire array is empty and method is set to intrp, switch method to fill - if (trim(method) .eq. 'intrp' .and. all_empty == 1) method='set_to_fill' + if (trim(method) .eq. 'intrp' .and. all_empty) method='set_to_fill' call handle_grib_error(vname, slevs(vlev),method,value,varnum,iret,var=dummy2d) if (iret==1) then ! missing_var_method == skip or no entry - if (trim(vname2)=="_1_0:" .or. trim(vname2) == "_1_1:" .or. & - trim(vname2) == ":14:192:") then + if ( (tracers_input_oct10(n) == 1 .and. tracers_input_oct11(n) == 0) .or. & ! spec humidity + (tracers_input_oct10(n) == 1 .and. tracers_input_oct11(n) == 1) .or. & ! rel humidity + (tracers_input_oct10(n) == 14 .and. tracers_input_oct11(n) == 192) ) then ! ozone call error_handler("READING IN "//trim(tracers(n))//" AT LEVEL "//trim(slevs(vlev))& //". SET A FILL VALUE IN THE VARMAP TABLE IF THIS ERROR IS NOT DESIRABLE.",iret) endif endif endif ! method intrp endif !iret<=0 - + if (n==1 .and. .not. hasspfh) then if (trim(external_model) .eq. 'GFS') then - print *,'CALRH GFS' + print *,'- CALL CALRH GFS' call rh2spfh_gfs(dummy2d,rlevs(vlev),dummy3d(:,:,vlev)) else - print *,'CALRH non-GFS' + print *,'- CALL CALRH non-GFS' call rh2spfh(dummy2d,rlevs(vlev),dummy3d(:,:,vlev)) end if endif - print*,'tracer ',vlev, maxval(dummy2d),minval(dummy2d) dummy3d(:,:,vlev) = real(dummy2d,esmf_kind_r8) + enddo !vlev + ! Jili Dong interpolation for missing levels - if (is_missing .gt. 0 .and. trim(method) .eq. 'intrp') then - print *,'intrp tracer '//trim(tracers(n)) + if (is_missing .and. trim(method) .eq. 'intrp') then + print *,'- INTERPOLATE TRACER '//trim(tracers(n)) done_print = 0 do jj = 1, j_input do ii = 1, i_input @@ -2841,7 +3055,7 @@ subroutine read_input_atm_grib2_file(localpet) endif ! intrp_missing ! zero out negative tracers from interpolation/extrapolation where(dummy3d(:,:,vlev) .lt. 0.0) dummy3d(:,:,vlev) = 0.0 - print*,'tracer af intrp',vlev, maxval(dummy3d(:,:,vlev)),minval(dummy3d(:,:,vlev)) +! print*,'tracer af intrp',vlev, maxval(dummy3d(:,:,vlev)),minval(dummy3d(:,:,vlev)) end do !nlevs do end if !if intrp endif !localpet == 0 @@ -2855,7 +3069,7 @@ subroutine read_input_atm_grib2_file(localpet) deallocate(dummy3d_col_in, dummy3d_col_out) -call read_winds(the_file,inv_file,u_tmp_3d,v_tmp_3d, localpet) + call read_winds(u_tmp_3d,v_tmp_3d,localpet,isnative,rlevs,lugb) if (localpet == 0) print*,"- CALL FieldScatter FOR INPUT U-WIND." call ESMF_FieldScatter(u_input_grid, u_tmp_3d, rootpet=0, rc=rc) @@ -2868,47 +3082,90 @@ subroutine read_input_atm_grib2_file(localpet) call error_handler("IN FieldScatter", rc) if (localpet == 0) then + print*,"- READ SURFACE PRESSURE." - vname = ":var0_2" - vname2 = "_3_0:" - vlevtyp = ":surface:" - iret = grb2_inq(the_file,inv_file,vname,vname2,vlevtyp,data2=dummy2d) - if (iret <= 0) call error_handler("READING SURFACE PRESSURE RECORD.", iret) - dummy2d_8 = real(dummy2d,esmf_kind_r8) - endif + jdisc = 0 ! search for discipline - meteorological products + j = 0 ! search at beginning of file. + jpdt = -9999 ! array of values in product definition template, set to wildcard + jids = -9999 ! array of values in identification section, set to wildcard + jgdt = -9999 ! array of values in grid definition template, set to wildcard + jgdtn = -1 ! search for any grid definition number. + jpdtn = 0 ! search for product def template number 0 - anl or fcst. + jpdt(1) = 3 ! Sect4/oct 10 - param category - mass + jpdt(2) = 0 ! Sect4/oct 11 - param number - pressure + jpdt(10) = 1 ! Sect4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + if (iret /= 0) call error_handler("READING SURFACE PRESSURE RECORD.", iret) + + dummy2d_8 = reshape(gfld%fld, (/i_input,j_input/) ) + + endif ! Read surface pressure if (localpet == 0) print*,"- CALL FieldScatter FOR INPUT GRID SURFACE PRESSURE." call ESMF_FieldScatter(ps_input_grid, dummy2d_8, rootpet=0, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldScatter", rc) +! Read dzdt. + if (localpet == 0) then + print*,"- READ DZDT." vname = "dzdt" call get_var_cond(vname,this_miss_var_method=method, this_miss_var_value=value, & loc=varnum) - vname = ":var0_2" - vname2 = "_2_9:" + + jdisc = 0 ! search for discipline - meteorological products + j = 0 ! search at beginning of file. + jpdt = -9999 ! array of values in product definition template, set to wildcard + jids = -9999 ! array of values in identification section, set to wildcard + jgdt = -9999 ! array of values in grid definition template, set to wildcard + jgdtn = -1 ! search for any grid definition number. + jpdtn = 0 ! search for product def template number 0 - anl or fcst. + jpdt(1) = 2 ! Sect4/oct 10 - param category - momentum + jpdt(2) = 9 ! Sect4/oct 11 - param number - dzdt + + if (isnative) then + jpdt(10) = 105 ! Sect4/oct 23 - type of level - hybrid + else + jpdt(10) = 100 ! Sect4/oct 23 - type of level - isobaric + endif + + unpack=.true. + do vlev = 1, lev_input - iret = grb2_inq(the_file,inv_file,vname,vname2,slevs(vlev),data2=dummy2d) - if (iret <= 0 ) then + + jpdt(12) = nint(rlevs(vlev)) + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret /= 0) then ! dzdt not found, look for omega. print*,"DZDT not available at level ", trim(slevs(vlev)), " so checking for VVEL" - vname2 = "_2_8:" - iret = grb2_inq(the_file,inv_file,vname,vname2,slevs(vlev),data2=dummy2d) - if (iret <= 0) then - call handle_grib_error(vname, slevs(vlev),method,value,varnum,iret,var=dummy2d) - if (iret==1) then ! missing_var_method == skip - cycle - endif + jpdt(2) = 8 ! Sect4/oct 11 - parameter number - omega + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + if (iret /= 0) then + call handle_grib_error(vname, slevs(vlev),method,value,varnum,iret,var8=dum2d_1) + if (iret==1) then ! missing_var_method == skip + cycle + endif else - conv_omega = .true. + conv_omega = .true. + dum2d_1 = reshape(gfld%fld, (/i_input,j_input/) ) endif - + else ! found dzdt + dum2d_1 = reshape(gfld%fld, (/i_input,j_input/) ) endif - print*,'dzdt ',vlev, maxval(dummy2d),minval(dummy2d) - dummy3d(:,:,vlev) = dummy2d + + dummy3d(:,:,vlev) = dum2d_1 + enddo - endif + + endif ! Read of dzdt call mpi_bcast(conv_omega,1,MPI_LOGICAL,0,MPI_COMM_WORLD,rc) @@ -2917,15 +3174,30 @@ subroutine read_input_atm_grib2_file(localpet) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldScatter", rc) +! Read terrain + if (localpet == 0) then + print*,"- READ TERRAIN." - vname = ":var0_2" - vname2 = "_3_5:" - vlevtyp = ":surface:" - iret = grb2_inq(the_file,inv_file,vname,vname2,vlevtyp,data2=dummy2d) - if (iret <= 0) call error_handler("READING TERRAIN HEIGHT RECORD.", iret) - dummy2d_8 = real(dummy2d,esmf_kind_r8) - endif + jdisc = 0 ! search for discipline - meteorological products + j = 0 ! search at beginning of file. + jpdt = -9999 ! array of values in product definition template, set to wildcard + jids = -9999 ! array of values in identification section, set to wildcard + jgdt = -9999 ! array of values in grid definition template, set to wildcard + jgdtn = -1 ! search for any grid definition number. + jpdtn = 0 ! search for product def template number 0 - anl or fcst. + jpdt(1) = 3 ! Sect4/oct 10 - param category - mass + jpdt(2) = 5 ! Sect4/oct 11 - param number - geopotential height + jpdt(10) = 1 ! Sect4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + if (iret /= 0) call error_handler("READING TERRAIN HEIGHT RECORD.", iret) + + dummy2d_8 = reshape(gfld%fld, (/i_input,j_input/) ) + + endif ! read of terrain. if (localpet == 0) print*,"- CALL FieldScatter FOR INPUT GRID TERRAIN." call ESMF_FieldScatter(terrain_input_grid, dummy2d_8, rootpet=0, rc=rc) @@ -2935,6 +3207,7 @@ subroutine read_input_atm_grib2_file(localpet) deallocate(dummy2d, dummy2d_8) if (.not. isnative) then + !--------------------------------------------------------------------------- ! Flip 'z' indices to all 3-d variables. Data is read in from model ! top to surface. This program expects surface to model top. @@ -3018,27 +3291,51 @@ subroutine read_input_atm_grib2_file(localpet) lev_input)),minval(presptr(clb(1):cub(1),clb(2):cub(2),lev_input)) endif -else - ! For native files, read in pressure field directly from file but don't flip levels +else ! is native coordinate (hybrid). + +! For native files, read in pressure field directly from file but don't flip levels + if (localpet == 0) then + print*,"- READ PRESSURE." - vname = ":PRES:" + + jdisc = 0 ! search for discipline - meteorological products + j = 0 ! search at beginning of file. + jpdt = -9999 ! array of values in product definition template, set to wildcard + jids = -9999 ! array of values in identification section, set to wildcard + jgdt = -9999 ! array of values in grid definition template, set to wildcard + jgdtn = -1 ! search for any grid definition number. + jpdtn = 0 ! search for product def template number 0 - anl or fcst. + jpdt(1) = 3 ! Sect4/oct 10 - param category - mass + jpdt(2) = 0 ! Sect4/oct 11 - param number - pressure + jpdt(10) = 105 ! Sect4/oct 23 - type of level - hybrid + unpack=.true. + do vlev = 1, lev_input - iret = grb2_inq(the_file,inv_file,vname,slevs(vlev),data2=dummy2d) - if (iret<=0) then + + jpdt(12) = nint(rlevs(vlev)) + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + if (iret /= 0) then call error_handler("READING IN PRESSURE AT LEVEL "//trim(slevs(vlev)),iret) endif - dummy3d(:,:,vlev) = real(dummy2d,esmf_kind_r8) - print*,'pres check after read ',vlev, dummy3d(1,1,vlev) + + dum2d_1 = reshape(gfld%fld, (/i_input,j_input/) ) + + dummy3d(:,:,vlev) = dum2d_1 + enddo - endif + + endif ! localpet == 0 if (localpet == 0) print*,"- CALL FieldScatter FOR INPUT GRID PRESSURE." call ESMF_FieldScatter(pres_input_grid, dummy3d, rootpet=0, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldScatter", rc) + endif - deallocate(dummy3d) + + deallocate(dummy3d, dum2d_1) !--------------------------------------------------------------------------- ! Convert from 2-d to 3-d component winds. @@ -3089,6 +3386,8 @@ subroutine read_input_atm_grib2_file(localpet) endif + if (localpet == 0) call baclose(lugb, rc) + end subroutine read_input_atm_grib2_file !> Read input grid surface data from a spectral gfs gaussian sfcio @@ -4700,55 +4999,100 @@ end subroutine read_input_sfc_netcdf_file !! @author Larissa Reames subroutine read_input_sfc_grib2_file(localpet) - use wgrib2api + use mpi + use grib_mod use program_setup, only : vgtyp_from_climo, sotyp_from_climo use model_grid, only : input_grid_type use search_util - implicit none integer, intent(in) :: localpet character(len=250) :: the_file character(len=250) :: geo_file - character(len=20) :: vname, vname_file,slev + character(len=20) :: vname, vname_file, slev character(len=50) :: method character(len=20) :: to_upper integer :: rc, varnum, iret, i, j,k integer :: ncid2d, varid, varsize + integer :: lugb, lugi + integer :: jdisc, jgdtn, jpdtn + integer :: jids(200), jgdt(200), jpdt(200) - logical :: exist, rap_latlon + logical :: rap_latlon, unpack real(esmf_kind_r4) :: value - - real(esmf_kind_r4), allocatable :: dummy2d(:,:),icec_save(:,:) + real(esmf_kind_r4), allocatable :: dummy2d(:,:) + real(esmf_kind_r8), allocatable :: icec_save(:,:) real(esmf_kind_r4), allocatable :: dummy1d(:) real(esmf_kind_r8), allocatable :: dummy2d_8(:,:),dummy2d_82(:,:),tsk_save(:,:) real(esmf_kind_r8), allocatable :: dummy3d(:,:,:), dummy3d_stype(:,:,:) integer(esmf_kind_i4), allocatable :: slmsk_save(:,:) integer(esmf_kind_i8), allocatable :: dummy2d_i(:,:) + type(gribfield) :: gfld rap_latlon = trim(to_upper(external_model))=="RAP" .and. trim(input_grid_type) == "rotated_latlon" the_file = trim(data_dir_input_grid) // "/" // trim(grib2_file_input_grid) geo_file = trim(geogrid_file_input_grid) - print*,"- READ SFC DATA FROM GRIB2 FILE: ", trim(the_file) - inquire(file=the_file,exist=exist) - if (.not.exist) then - iret = 1 - call error_handler("OPENING GRIB2 FILE.", iret) - end if - - lsoil_input = grb2_inq(the_file, inv_file, ':TSOIL:',' below ground:') - print*, "- FILE HAS ", lsoil_input, " SOIL LEVELS" - if (lsoil_input <= 0) call error_handler("COUNTING SOIL LEVELS.", rc) - - !We need to recreate the soil fields if we have something other than 4 levels + +! Determine the number of soil layers in file. + + if (localpet == 0) then + + lugb=12 + call baopenr(lugb,the_file,rc) + if (rc /= 0) call error_handler("ERROR OPENING GRIB2 FILE.", rc) + + j = 0 ! search at beginning of file + lugi = 0 ! no grib index file + jdisc = -1 ! search for any discipline + jpdtn = -1 ! search for any product definition template number + jgdtn = -1 ! search for any grid definition template number + jids = -9999 ! array of values in identification section, set to wildcard + jgdt = -9999 ! array of values in grid definition template, set to wildcard + jpdt = -9999 ! array of values in product definition template, set to wildcard + unpack = .false. ! unpack data + + lsoil_input = 0 + do + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0) exit + + if (gfld%discipline == 2) then ! discipline - land products + if (gfld%ipdtnum == 0) then ! prod template number - analysis or forecast at single level. + if (gfld%ipdtmpl(1) == 0 .and. gfld%ipdtmpl(2) == 2) then ! soil temp + ! Sect4/octs 10 and 11 + if (gfld%ipdtmpl(10) == 106 .and. gfld%ipdtmpl(13) == 106) then ! Sect4/octs 23/29. + ! Layer below ground. + lsoil_input = lsoil_input + 1 + endif + endif + endif + endif + + j = k + + enddo + + print*, "- FILE HAS ", lsoil_input, " SOIL LEVELS." + if (lsoil_input == 0) call error_handler("COUNTING SOIL LEVELS.", rc) + + endif ! localpet == 0 + + call MPI_BARRIER(MPI_COMM_WORLD, rc) + call MPI_BCAST(lsoil_input,1,MPI_INTEGER,0,MPI_COMM_WORLD,rc) + + ! We need to recreate the soil fields if we have something other than 4 levels + if (lsoil_input /= 4) then call ESMF_FieldDestroy(soil_temp_input_grid, rc=rc) @@ -4783,56 +5127,81 @@ subroutine read_input_sfc_grib2_file(localpet) call error_handler("IN FieldCreate", rc) endif - - if (localpet == 0) then - allocate(dummy2d(i_input,j_input)) - allocate(slmsk_save(i_input,j_input)) - allocate(dummy2d_i(i_input,j_input)) - allocate(tsk_save(i_input,j_input)) - allocate(icec_save(i_input,j_input)) - allocate(dummy2d_8(i_input,j_input)) - allocate(dummy2d_82(i_input,j_input)) - allocate(dummy3d(i_input,j_input,lsoil_input)) - allocate(dummy3d_stype(i_input,j_input,16)) - allocate(dummy1d(16)) - else - allocate(dummy3d(0,0,0)) - allocate(dummy2d_8(0,0)) - allocate(dummy2d_82(0,0)) - allocate(dummy2d(0,0)) - allocate(slmsk_save(0,0)) - endif + + if (localpet == 0) then + allocate(dummy2d(i_input,j_input)) + allocate(slmsk_save(i_input,j_input)) + allocate(tsk_save(i_input,j_input)) + allocate(icec_save(i_input,j_input)) + allocate(dummy2d_8(i_input,j_input)) + allocate(dummy2d_82(i_input,j_input)) + allocate(dummy3d(i_input,j_input,lsoil_input)) + else + allocate(dummy3d(0,0,0)) + allocate(dummy2d_8(0,0)) + allocate(dummy2d_82(0,0)) + allocate(dummy2d(0,0)) + allocate(slmsk_save(0,0)) + endif !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! These variables are always in grib files, or are required, so no need to check for them ! in the varmap table. If they can't be found in the input file, then stop the program. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - if (localpet == 0) then - print*,"- READ TERRAIN." - rc = grb2_inq(the_file, inv_file, ':HGT:',':surface:', data2=dummy2d) - if (rc /= 1) call error_handler("READING TERRAIN.", rc) - print*,'orog ',maxval(dummy2d),minval(dummy2d) - endif + if (localpet == 0) then - print*,"- CALL FieldScatter FOR INPUT TERRAIN." - call ESMF_FieldScatter(terrain_input_grid, real(dummy2d,esmf_kind_r8),rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + print*,"- READ TERRAIN." + + j = 0 + jdisc = 0 ! Search for discipline 0 - meteorological products + jpdt = -9999 ! array of values in product definition template, set to wildcard. + jpdtn = 0 ! search for product definition template number 0 - anl or fcst. + jpdt(1) = 3 ! Sec4/oct 10 - param cat - mass field + jpdt(2) = 5 ! Sec4/oct 11 - param number - geopotential height + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /= 0) call error_handler("READING TERRAIN.", rc) + + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) +! print*,'orog ', maxval(dummy2d_8),minval(dummy2d_8) + + endif + + print*,"- CALL FieldScatter FOR INPUT TERRAIN." + call ESMF_FieldScatter(terrain_input_grid, dummy2d_8, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) -if (localpet == 0) then - print*,"- READ SEAICE FRACTION." - rc = grb2_inq(the_file, inv_file, ':ICEC:',':surface:', data2=dummy2d) - if (rc /= 1) call error_handler("READING SEAICE FRACTION.", rc) - !dummy2d = dummy2d(i_input:1:-1,j_input:1:-1) - print*,'icec ',maxval(dummy2d),minval(dummy2d) - icec_save = dummy2d - endif + if (localpet == 0) then - print*,"- CALL FieldScatter FOR INPUT GRID SEAICE FRACTION." - call ESMF_FieldScatter(seaice_fract_input_grid,real(dummy2d,esmf_kind_r8),rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + print*,"- READ SEAICE FRACTION." + + jdisc = 10 ! Search for discipline - ocean products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Array of values in Sec 4 product definition template; + ! Initialize to wildcard. + jpdt(1) = 2 ! Sec4/oct 10 - parameter category - ice + jpdt(2) = 0 ! Sec4/oct 11 - parameter number - ice cover + unpack=.true. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /= 0) call error_handler("READING SEAICE FRACTION.", rc) + + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) +! print*,'icec ', maxval(dummy2d_8),minval(dummy2d_8) + + icec_save = dummy2d_8 + + endif + + print*,"- CALL FieldScatter FOR INPUT GRID SEAICE FRACTION." + call ESMF_FieldScatter(seaice_fract_input_grid, dummy2d_8 ,rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) !---------------------------------------------------------------------------------- ! GFS v14 and v15.2 grib data has two land masks. LANDN is created by @@ -4842,46 +5211,89 @@ subroutine read_input_sfc_grib2_file(localpet) ! '2' based on ice concentration. !---------------------------------------------------------------------------------- - if (localpet == 0) then - print*,"- READ LANDSEA MASK." - rc = grb2_inq(the_file, inv_file, ':LANDN:',':surface:', data2=dummy2d) + if (localpet == 0) then - if (rc /= 1) then - rc = grb2_inq(the_file, inv_file, ':LAND:',':surface:', data2=dummy2d) - if (rc /= 1) call error_handler("READING LANDSEA MASK.", rc) - endif + print*,"- READ LANDSEA MASK." - do j = 1, j_input - do i = 1, i_input - if(dummy2d(i,j) < 0.5_esmf_kind_r4) dummy2d(i,j)=0.0_esmf_kind_r4 - if(icec_save(i,j) > 0.15_esmf_kind_r4) then - !if (dummy2d(i,j) == 0.0_esmf_kind_r4) print*, "CONVERTING WATER TO SEA/LAKE ICE AT ", i, j - dummy2d(i,j) = 2.0_esmf_kind_r4 - endif + jdisc = 2 ! Search for discipline - land products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product definition template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template - Sec 4. + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - veg/biomass + jpdt(2) = 218 ! Sec4/oct 11 - parameter number - land nearest neighbor + unpack=.true. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc == 0) then + + print*,'landnn ', maxval(gfld%fld),minval(gfld%fld) + + else + + jdisc = 2 ! Search for discipline - land products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template - Sec 4. + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - veg/biomass + jpdt(2) = 0 ! Sec4/oct 11 - parameter number - land cover (fraction) + unpack=.true. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /= 0) call error_handler("READING LANDSEA MASK.", rc) + +! print*,'land ', maxval(gfld%fld),minval(gfld%fld) + + endif + + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + do j = 1, j_input + do i = 1, i_input + if(dummy2d_8(i,j) < 0.5_esmf_kind_r8) dummy2d_8(i,j)=0.0 + if(icec_save(i,j) > 0.15_esmf_kind_r8) then + dummy2d_8(i,j) = 2.0_esmf_kind_r8 + endif + enddo enddo - enddo - slmsk_save = nint(dummy2d) - - deallocate(icec_save) - endif ! localpet == 0 + slmsk_save = nint(dummy2d_8) - print*,"- CALL FieldScatter FOR INPUT LANDSEA MASK." - call ESMF_FieldScatter(landsea_mask_input_grid,real(dummy2d,esmf_kind_r8),rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + deallocate(icec_save) - if (localpet == 0) then - print*,"- READ SEAICE SKIN TEMPERATURE." - rc = grb2_inq(the_file, inv_file, ':TMP:',':surface:', data2=dummy2d) - if (rc /= 1) call error_handler("READING SEAICE SKIN TEMP.", rc) - print*,'ti ',maxval(dummy2d),minval(dummy2d) - endif + endif ! read land mask - print*,"- CALL FieldScatter FOR INPUT GRID SEAICE SKIN TEMPERATURE." - call ESMF_FieldScatter(seaice_skin_temp_input_grid,real(dummy2d,esmf_kind_r8),rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + print*,"- CALL FieldScatter FOR INPUT LANDSEA MASK." + call ESMF_FieldScatter(landsea_mask_input_grid, dummy2d_8 ,rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + if (localpet == 0) then + + print*,"- READ SEAICE SKIN TEMPERATURE." + + jdisc = 0 ! Search for discipline - meteorological products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product definition template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template - Sec4 + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - temperature + jpdt(2) = 0 ! Sec4/oct 11 - parameter number - temperature + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /= 0) call error_handler("READING SEAICE SKIN TEMP.", rc) + +! print*,'ti ',maxval(gfld%fld),minval(gfld%fld) + + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + endif + + print*,"- CALL FieldScatter FOR INPUT GRID SEAICE SKIN TEMPERATURE." + call ESMF_FieldScatter(seaice_skin_temp_input_grid, dummy2d_8 ,rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) !---------------------------------------------------------------------------------- ! Read snow fields. Zero out at non-land points and undefined points (points @@ -4889,145 +5301,250 @@ subroutine read_input_sfc_grib2_file(localpet) ! in mm. !---------------------------------------------------------------------------------- - if (localpet == 0) then - print*,"- READ SNOW LIQUID EQUIVALENT." - rc = grb2_inq(the_file, inv_file, ':WEASD:',':surface:',':anl:',data2=dummy2d) - if (rc /= 1) then - rc = grb2_inq(the_file, inv_file, ':WEASD:',':surface:','hour fcst:',data2=dummy2d) - if (rc /= 1) call error_handler("READING SNOW LIQUID EQUIVALENT.", rc) + if (localpet == 0) then + + print*,"- READ SNOW LIQUID EQUIVALENT." + + jdisc = 0 ! Search for discipline - meteorological products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product definition template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template - Sec4 + jpdt(1) = 1 ! Sec4/oct 10 - parameter category - moisture + jpdt(2) = 13 ! Sec4/oct 11 - parameter number - liquid equiv snow depth + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /= 0) call error_handler("READING SNOW LIQUID EQUIVALENT.", rc) + +! print*,'weasd ', maxval(gfld%fld),minval(gfld%fld) + + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + do j = 1, j_input + do i = 1, i_input + if(slmsk_save(i,j) == 0) dummy2d_8(i,j) = 0.0 + enddo + enddo + endif - do j = 1, j_input + + print*,"- CALL FieldScatter FOR INPUT GRID SNOW LIQUID EQUIVALENT." + call ESMF_FieldScatter(snow_liq_equiv_input_grid, dummy2d_8 ,rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + if (localpet == 0) then + + print*,"- READ SNOW DEPTH." + + jdisc = 0 ! Search for discipline - meteorological products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product definition template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template - Sec4 + jpdt(1) = 1 ! Sec4/oct 10 - parameter category - moisture + jpdt(2) = 11 ! Sec4/oct 11 - parameter number - snow depth + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0) then + call error_handler("READING SNOW DEPTH.", rc) + else + gfld%fld = gfld%fld * 1000.0 +! print*,'snod ', maxval(gfld%fld),minval(gfld%fld) + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + endif + + do j = 1, j_input do i = 1, i_input - if(slmsk_save(i,j) == 0) dummy2d(i,j) = 0.0_esmf_kind_r4 - if(dummy2d(i,j) == grb2_UNDEFINED) dummy2d(i,j) = 0.0_esmf_kind_r4 + if(slmsk_save(i,j) == 0) dummy2d_8(i,j) = 0.0 + enddo enddo - enddo - print*,'weasd ',maxval(dummy2d),minval(dummy2d) - endif - - print*,"- CALL FieldScatter FOR INPUT GRID SNOW LIQUID EQUIVALENT." - call ESMF_FieldScatter(snow_liq_equiv_input_grid,real(dummy2d,esmf_kind_r8),rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) - if (localpet == 0) then - print*,"- READ SNOW DEPTH." - rc = grb2_inq(the_file, inv_file, ':SNOD:',':surface:', data2=dummy2d) - if (rc /= 1) call error_handler("READING SNOW DEPTH.", rc) - where(dummy2d == grb2_UNDEFINED) dummy2d = 0.0_esmf_kind_r4 - dummy2d = dummy2d*1000.0 ! Grib2 files have snow depth in (m), fv3 expects it in mm - where(slmsk_save == 0) dummy2d = 0.0_esmf_kind_r4 - print*,'snod ',maxval(dummy2d),minval(dummy2d) - endif + endif - print*,"- CALL FieldScatter FOR INPUT GRID SNOW DEPTH." - call ESMF_FieldScatter(snow_depth_input_grid,real(dummy2d,esmf_kind_r8),rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + print*,"- CALL FieldScatter FOR INPUT GRID SNOW DEPTH." + call ESMF_FieldScatter(snow_depth_input_grid,dummy2d_8,rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) - if (localpet == 0) then - print*,"- READ T2M." - rc = grb2_inq(the_file, inv_file, ':TMP:',':2 m above ground:',data2=dummy2d) - if (rc <= 0) call error_handler("READING T2M.", rc) + if (localpet == 0) then - print*,'t2m ',maxval(dummy2d),minval(dummy2d) - endif + print*,"- READ T2M." - print*,"- CALL FieldScatter FOR INPUT GRID T2M." - call ESMF_FieldScatter(t2m_input_grid,real(dummy2d,esmf_kind_r8), rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + jdisc = 0 ! Search for discipline - meteorological products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template - Sec4 + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - temperature + jpdt(2) = 0 ! Sec4/oct 11 - parameter number - temperature + jpdt(10) = 103 ! Sec4/oct 23 - type of level - height above ground surface + jpdt(12) = 2 ! Sec4/octs 25-28 - 2 meters above ground. + unpack=.true. - if (localpet == 0) then - print*,"- READ Q2M." - rc = grb2_inq(the_file, inv_file, ':SPFH:',':2 m above ground:',data2=dummy2d) - if (rc <=0) call error_handler("READING Q2M.", rc) - print*,'q2m ',maxval(dummy2d),minval(dummy2d) - endif + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) - print*,"- CALL FieldScatter FOR INPUT GRID Q2M." - call ESMF_FieldScatter(q2m_input_grid,real(dummy2d,esmf_kind_r8), rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + if (rc /= 0) call error_handler("READING T2M.", rc) +! print*,'t2m ', maxval(gfld%fld),minval(gfld%fld) + + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + endif + + print*,"- CALL FieldScatter FOR INPUT GRID T2M." + call ESMF_FieldScatter(t2m_input_grid, dummy2d_8, rootpet=0,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + if (localpet == 0) then + + print*,"- READ Q2M." + + jdisc = 0 ! Search for discipline - meteorological products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product definition template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template - Sec4 + jpdt(1) = 1 ! Sec4/oct 10 - parameter category - moisture + jpdt(2) = 0 ! Sec4/oct 11 - parameter number - specific humidity + jpdt(10) = 103 ! Sec4/oct 23 - type of level - height above ground surface + jpdt(12) = 2 ! Sec4/octs 25-28 - 2 meters above ground. + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /=0) call error_handler("READING Q2M.", rc) + +! print*,'q2m ',maxval(gfld%fld),minval(gfld%fld) + + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + endif + + print*,"- CALL FieldScatter FOR INPUT GRID Q2M." + call ESMF_FieldScatter(q2m_input_grid,dummy2d_8, rootpet=0,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) - if (localpet == 0) then - print*,"- READ SKIN TEMPERATURE." - rc = grb2_inq(the_file, inv_file, ':TMP:',':surface:', data2=dummy2d) - if (rc <= 0 ) call error_handler("READING SKIN TEMPERATURE.", rc) - tsk_save(:,:) = real(dummy2d,esmf_kind_r8) - dummy2d_8 = real(dummy2d,esmf_kind_r8) - do j = 1, j_input - do i = 1, i_input - if(slmsk_save(i,j) == 0 .and. dummy2d(i,j) < 271.2) then -! print*,'too cool SST ',i,j,dummy2d(i,j) - dummy2d(i,j) = 271.2 - endif - if(slmsk_save(i,j) == 0 .and. dummy2d(i,j) > 310.) then -! print*,'too hot SST ',i,j,dummy2d(i,j) - dummy2d(i,j) = 310.0 - endif + if (localpet == 0) then + + print*,"- READ SKIN TEMPERATURE." + + jdisc = 0 ! Search for discipline - meteorological products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product definition template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template - Sec4 + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - temperature + jpdt(2) = 0 ! Sec4/oct 11 - parameter number - temperature + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0 ) call error_handler("READING SKIN TEMPERATURE.", rc) +! print*,'skint ', maxval(gfld%fld),minval(gfld%fld) + + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + tsk_save(:,:) = dummy2d_8 + + do j = 1, j_input + do i = 1, i_input + if(slmsk_save(i,j) == 0 .and. dummy2d_8(i,j) < 271.2) then +! print*,'too cool SST ',i,j,dummy2d_8(i,j) + dummy2d_8(i,j) = 271.2 + endif + if(slmsk_save(i,j) == 0 .and. dummy2d_8(i,j) > 310.) then +! print*,'too hot SST ',i,j,dummy2d_8(i,j) + dummy2d_8(i,j) = 310.0 + endif + enddo enddo - enddo - endif - print*,"- CALL FieldScatter FOR INPUT GRID SKIN TEMPERATURE" - call ESMF_FieldScatter(skin_temp_input_grid,real(dummy2d,esmf_kind_r8),rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + endif + + print*,"- CALL FieldScatter FOR INPUT GRID SKIN TEMPERATURE" + call ESMF_FieldScatter(skin_temp_input_grid,dummy2d_8,rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) - if (localpet == 0) dummy2d = 0.0 +! srflag not in files. Set to zero. + + if (localpet == 0) dummy2d_8 = 0.0 - print*,"- CALL FieldScatter FOR INPUT GRID SRFLAG" - call ESMF_FieldScatter(srflag_input_grid,real(dummy2d,esmf_kind_r8), rootpet=0,rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + print*,"- CALL FieldScatter FOR INPUT GRID SRFLAG" + call ESMF_FieldScatter(srflag_input_grid,dummy2d_8, rootpet=0,rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) - if (localpet == 0) then - print*,"- READ SOIL TYPE." - slev=":surface:" - vname=":SOTYP:" - rc = grb2_inq(the_file, inv_file, vname,slev, data2=dummy2d) - !failed => rc = 0 - if (rc <= 0 .and. (trim(to_upper(external_model))=="HRRR" .or. rap_latlon) .and. geo_file .ne. "NULL") then + if (localpet == 0) then + + print*,"- READ SOIL TYPE." + + jdisc = 2 ! Search for discipline - land products + j = 0 ! Search at beginning of file + jpdtn = 0 ! Search for product definition template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template - Sec4 + jpdt(1) = 3 ! Sec4/oct 10 - parameter category - soil products + jpdt(2) = 0 ! Sec4/oct 11 - parameter number - soil type + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc == 0 ) then +! print*,'soil type ', maxval(gfld%fld),minval(gfld%fld) + dummy2d = reshape(gfld%fld , (/i_input,j_input/)) + + endif + + if (rc /= 0 .and. (trim(to_upper(external_model))=="HRRR" .or. rap_latlon) .and. geo_file .ne. "NULL") then ! Some HRRR and RAP files don't have dominant soil type in the output, but the geogrid files ! do, so this gives users the option to provide the geogrid file and use input soil ! type - print*, "OPEN GEOGRID FILE ", trim(geo_file) - rc = nf90_open(geo_file,NF90_NOWRITE,ncid2d) - call netcdf_err(rc,"READING GEOGRID FILE") + print*, "OPEN GEOGRID FILE ", trim(geo_file) + rc = nf90_open(geo_file,NF90_NOWRITE,ncid2d) + call netcdf_err(rc,"READING GEOGRID FILE") - print*, "INQURE ABOUT DIM IDS" - rc = nf90_inq_dimid(ncid2d,"west_east",varid) - call netcdf_err(rc,"READING west_east DIMENSION FROM GEOGRID FILE") + print*, "INQURE ABOUT DIM IDS" + rc = nf90_inq_dimid(ncid2d,"west_east",varid) + call netcdf_err(rc,"READING west_east DIMENSION FROM GEOGRID FILE") - rc = nf90_inquire_dimension(ncid2d,varid,len=varsize) - call netcdf_err(rc,"READING west_east DIMENSION SIZE") - if (varsize .ne. i_input) call error_handler ("GEOGRID FILE GRID SIZE DIFFERS FROM INPUT DATA.", -1) + rc = nf90_inquire_dimension(ncid2d,varid,len=varsize) + call netcdf_err(rc,"READING west_east DIMENSION SIZE") + if (varsize .ne. i_input) call error_handler ("GEOGRID FILE GRID SIZE DIFFERS FROM INPUT DATA.", -1) - print*, "INQUIRE ABOUT SOIL TYPE FROM GEOGRID FILE" - rc = nf90_inq_varid(ncid2d,"SCT_DOM",varid) - call netcdf_err(rc,"FINDING SCT_DOM IN GEOGRID FILE") + print*, "INQUIRE ABOUT SOIL TYPE FROM GEOGRID FILE" + rc = nf90_inq_varid(ncid2d,"SCT_DOM",varid) + call netcdf_err(rc,"FINDING SCT_DOM IN GEOGRID FILE") - print*, "READ SOIL TYPE FROM GEOGRID FILE " - rc = nf90_get_var(ncid2d,varid,dummy2d) - call netcdf_err(rc,"READING SCT_DOM FROM FILE") + print*, "READ SOIL TYPE FROM GEOGRID FILE " + rc = nf90_get_var(ncid2d,varid,dummy2d) + call netcdf_err(rc,"READING SCT_DOM FROM FILE") - print*, "INQUIRE ABOUT SOIL TYPE FRACTIONS FROM GEOGRID FILE" - rc = nf90_inq_varid(ncid2d,"SOILCTOP",varid) - call netcdf_err(rc,"FINDING SOILCTOP IN GEOGRID FILE") + print*, "INQUIRE ABOUT SOIL TYPE FRACTIONS FROM GEOGRID FILE" + rc = nf90_inq_varid(ncid2d,"SOILCTOP",varid) + call netcdf_err(rc,"FINDING SOILCTOP IN GEOGRID FILE") - print*, "READ SOIL TYPE FRACTIONS FROM GEOGRID FILE " - rc = nf90_get_var(ncid2d,varid,dummy3d_stype) - call netcdf_err(rc,"READING SCT_DOM FROM FILE") + allocate(dummy3d_stype(i_input,j_input,16)) + print*, "READ SOIL TYPE FRACTIONS FROM GEOGRID FILE " + rc = nf90_get_var(ncid2d,varid,dummy3d_stype) + call netcdf_err(rc,"READING SCT_DOM FROM FILE") - print*, "CLOSE GEOGRID FILE " - iret = nf90_close(ncid2d) - + print*, "CLOSE GEOGRID FILE " + iret = nf90_close(ncid2d) ! There's an issue with the geogrid file containing soil type water at land points. ! This correction replaces the soil type at these points with the soil type with ! the next highest fractional coverage. - do j = 1, j_input + allocate(dummy1d(16)) + do j = 1, j_input do i = 1, i_input if(dummy2d(i,j) == 14.0_esmf_kind_r4 .and. slmsk_save(i,j) == 1) then dummy1d(:) = dummy3d_stype(i,j,:) @@ -5035,396 +5552,501 @@ subroutine read_input_sfc_grib2_file(localpet) dummy2d(i,j) = real(MAXLOC(dummy1d, 1),esmf_kind_r4) endif enddo - enddo - deallocate(dummy1d) - endif ! localpet == 0 + enddo + deallocate(dummy1d) + deallocate(dummy3d_stype) + endif ! failed - if ((rc <= 0 .and. trim(to_upper(external_model)) /= "HRRR" .and. .not. rap_latlon) & - .or. (rc < 0 .and. (trim(to_upper(external_model)) == "HRRR" .or. rap_latlon))) then - if (.not. sotyp_from_climo) then - call error_handler("COULD NOT FIND SOIL TYPE IN FILE. PLEASE SET SOTYP_FROM_CLIMO=.TRUE. . EXITING", rc) - else - vname = "sotyp" - call get_var_cond(vname,this_miss_var_method=method, this_miss_var_value=value, & - loc=varnum) - call handle_grib_error(vname, slev ,method,value,varnum,rc, var= dummy2d) - if (rc == 1) then ! missing_var_method == skip or no entry in varmap table - print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. WILL NOT "//& - "SCALE SOIL MOISTURE FOR DIFFERENCES IN SOIL TYPE. " - dummy2d(:,:) = -99999.0_esmf_kind_r4 + if ((rc /= 0 .and. trim(to_upper(external_model)) /= "HRRR" .and. .not. rap_latlon) & + .or. (rc /= 0 .and. (trim(to_upper(external_model)) == "HRRR" .or. rap_latlon))) then + if (.not. sotyp_from_climo) then + call error_handler("COULD NOT FIND SOIL TYPE IN FILE. PLEASE SET SOTYP_FROM_CLIMO=.TRUE. . EXITING", rc) + else + vname = "sotyp" + slev = "surface" + call get_var_cond(vname,this_miss_var_method=method, this_miss_var_value=value, & + loc=varnum) + call handle_grib_error(vname, slev ,method,value,varnum,rc, var= dummy2d) + if (rc == 1) then ! missing_var_method == skip or no entry in varmap table + print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. WILL NOT "//& + "SCALE SOIL MOISTURE FOR DIFFERENCES IN SOIL TYPE. " + dummy2d(:,:) = -99999.0_esmf_kind_r4 + endif endif endif - endif ! In the event that the soil type on the input grid still contains mismatches between ! soil type and landmask, this correction is a last-ditch effort to replace these points ! with soil type from a nearby land point. - if (.not. sotyp_from_climo) then - do j = 1, j_input - do i = 1, i_input - if(dummy2d(i,j) == 14.0_esmf_kind_r4 .and. slmsk_save(i,j) == 1) dummy2d(i,j) = -99999.9 - enddo - enddo - - dummy2d_8 = real(dummy2d,esmf_kind_r8) - dummy2d_i(:,:) = 0 - where(slmsk_save == 1) dummy2d_i = 1 + + if (.not. sotyp_from_climo) then + do j = 1, j_input + do i = 1, i_input + if(dummy2d(i,j) == 14.0_esmf_kind_r4 .and. slmsk_save(i,j) == 1) dummy2d(i,j) = -99999.9 + enddo + enddo + + allocate(dummy2d_i(i_input,j_input)) + dummy2d_8 = real(dummy2d,esmf_kind_r8) + dummy2d_i(:,:) = 0 + where(slmsk_save == 1) dummy2d_i = 1 - call search(dummy2d_8,dummy2d_i,i_input,j_input,1,230) - else - dummy2d_8=real(dummy2d,esmf_kind_r8) - endif + call search(dummy2d_8,dummy2d_i,i_input,j_input,1,230) + deallocate(dummy2d_i) + else + dummy2d_8=real(dummy2d,esmf_kind_r8) + endif - print*,'sotype ',maxval(dummy2d_8),minval(dummy2d_8) - deallocate(dummy2d_i) - deallocate(dummy3d_stype) - endif ! localpet == 0 + print*,'sotype ',maxval(dummy2d_8),minval(dummy2d_8) + + endif ! read of soil type + print*,"- CALL FieldScatter FOR INPUT GRID SOIL TYPE." + call ESMF_FieldScatter(soil_type_input_grid,dummy2d_8, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) - print*,"- CALL FieldScatter FOR INPUT GRID SOIL TYPE." - call ESMF_FieldScatter(soil_type_input_grid,dummy2d_8, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + deallocate(dummy2d) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Begin variables whose presence in grib2 files varies, but no climatological ! data is available, so we have to account for values in the varmap table !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - if (.not. vgfrc_from_climo) then - if (localpet == 0) then - print*,"- READ VEG FRACTION." - vname="vfrac" - slev=":surface:" - call get_var_cond(vname,this_miss_var_method=method, this_miss_var_value=value, & - loc=varnum) - !! Changing these for GSD internal runs using new HRRR files - vname=":VEG:" - rc= grb2_inq(the_file, inv_file, vname,slev, data2=dummy2d) - - if (rc > 1) then - rc= grb2_inq(the_file, inv_file, vname,slev,'n=1105:', data2=dummy2d) - if (rc <= 0) then - rc= grb2_inq(the_file, inv_file, vname,slev,'n=1101:', data2=dummy2d) - if (rc <= 0) then - rc= grb2_inq(the_file, inv_file, vname,slev,'n=1151:', data2=dummy2d) - if (rc <= 0) call error_handler("COULD NOT DETERMINE VEGETATION FRACTION IN FILE. & - RECORD NUMBERS MAY HAVE CHANGED. PLEASE SET VGFRC_FROM_CLIMO=.TRUE. EXITING", rc) - endif - endif - elseif (rc <= 0) then - call error_handler("COULD NOT FIND VEGETATION FRACTION IN FILE. & + if (.not. vgfrc_from_climo) then + + if (localpet == 0) then + + print*,"- READ VEG FRACTION." + + jdisc = 2 ! Search for discipline - land products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product definition template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template Sec4. + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - veg/biomass + jpdt(2) = 4 ! Sec4/oct 11 - parameter number - vegetation + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0 )then + call error_handler("COULD NOT FIND VEGETATION FRACTION IN FILE. & PLEASE SET VGFRC_FROM_CLIMO=.TRUE. EXITING", rc) - endif - if(maxval(dummy2d) > 2.0) dummy2d = dummy2d / 100.0_esmf_kind_r4 - print*,'vfrac ',maxval(dummy2d),minval(dummy2d) + else + if (maxval(gfld%fld) > 2.0) gfld%fld = gfld%fld / 100.0 +! print*,'vfrac ', maxval(gfld%fld),minval(gfld%fld) + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + endif + + endif ! localpet 0 + + print*,"- CALL FieldScatter FOR INPUT GRID VEG GREENNESS." + call ESMF_FieldScatter(veg_greenness_input_grid,dummy2d_8, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & + call error_handler("IN FieldScatter", rc) + endif + if (.not. minmax_vgfrc_from_climo) then + + if (localpet == 0) then + + print*,"- READ MIN VEG FRACTION." + + jdisc = 2 ! Search for discipline - land products + j = 1105 ! grib2 file does not distinguish between the various veg + ! fractions. Need to search using record number. + jpdtn = 0 ! Search for product definition template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template Sec4. + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - veg/biomass + jpdt(2) = 4 ! Sec4/oct 11 - parameter number - vegetation + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0) then + j = 1101 ! Have to search by record number. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /= 0) then + j = 1151 ! Have to search by record number. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc/=0) call error_handler("COULD NOT FIND MIN VEGETATION FRACTION IN FILE. & + PLEASE SET MINMAX_VGFRC_FROM_CLIMO=.TRUE. . EXITING",rc) + endif + endif + + if (maxval(gfld%fld) > 2.0) gfld%fld = gfld%fld / 100.0 + print*,'vfrac min ', maxval(gfld%fld),minval(gfld%fld) + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + endif ! localpet == 0 + + print*,"- CALL FieldScatter FOR INPUT GRID MIN VEG GREENNESS." + call ESMF_FieldScatter(min_veg_greenness_input_grid,dummy2d_8, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + if (localpet == 0) then + + print*,"- READ MAX VEG FRACTION." + + jdisc = 2 ! Search for discipline - land products + j = 1106 ! Have to search by record number. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template Sec4. + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - veg/biomass + jpdt(2) = 4 ! Sec4/oct 11 - parameter number - vegetation + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /= 0) then + j = 1102 ! Have to search by record number. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /= 0) then + j = 1152 ! Have to search by record number. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc <= 0) call error_handler("COULD NOT FIND MAX VEGETATION FRACTION IN FILE. & + PLEASE SET MINMAX_VGFRC_FROM_CLIMO=.TRUE. . EXITING",rc) + endif + endif + + if (maxval(gfld%fld) > 2.0) gfld%fld = gfld%fld / 100.0 +! print*,'vfrac max ', maxval(gfld%fld),minval(gfld%fld) + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + endif !localpet==0 + + print*,"- CALL FieldScatter FOR INPUT GRID MAX VEG GREENNESS." + call ESMF_FieldScatter(max_veg_greenness_input_grid,dummy2d_8,rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + endif !minmax_vgfrc_from_climo - print*,"- CALL FieldScatter FOR INPUT GRID VEG GREENNESS." - call ESMF_FieldScatter(veg_greenness_input_grid,real(dummy2d,esmf_kind_r8), rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldScatter", rc) - endif + if (.not. lai_from_climo) then + + if (localpet == 0) then + + print*,"- READ LAI." + + jdisc = 0 ! Search for discipline - meteorological products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template Sec4. + jpdt(1) = 7 ! Sec4/oct 10 - parameter category - thermo stability indices + jpdt(2) = 198 ! Sec4/oct 11 - parameter number - leaf area index + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0) call error_handler("COULD NOT FIND LAI IN FILE. & + PLEASE SET LAI_FROM_CLIMO=.TRUE. . EXITING",rc) + +! print*,'lai ', maxval(gfld%fld),minval(gfld%fld) + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + + endif !localpet==0 + + print*,"- CALL FieldScatter FOR INPUT GRID LAI." + call ESMF_FieldScatter(lai_input_grid,dummy2d_8,rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + endif ! lai - if (.not. minmax_vgfrc_from_climo) then if (localpet == 0) then - print*,"- READ MIN VEG FRACTION." - vname="vfrac_min" - slev=":surface:" + + print*,"- READ SEAICE DEPTH." + vname="hice" + slev=":surface:" call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & - loc=varnum) - vname=":VEG:" - rc= grb2_inq(the_file, inv_file, vname,slev,'n=1106:',data2=dummy2d) - - if (rc <= 0) then - rc= grb2_inq(the_file, inv_file, vname,slev,'n=1102:',data2=dummy2d) - if (rc <= 0) then - rc= grb2_inq(the_file, inv_file, vname,slev,'n=1152:',data2=dummy2d) - if (rc<=0) call error_handler("COULD NOT FIND MIN VEGETATION FRACTION IN FILE. & - PLEASE SET MINMAX_VGFRC_FROM_CLIMO=.TRUE. . EXITING",rc) + loc=varnum) + + jdisc = 10 ! Search for discipline - ocean products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template Sec4. + jpdt(1) = 2 ! Sec4/oct 10 - parameter category - ice + jpdt(2) = 1 ! Sec4/oct 11 - parameter number - thickness + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0 ) then + call handle_grib_error(vname, slev ,method,value,varnum,rc,var8=dummy2d_8) + if (rc==1) then ! missing_var_method == skip or no entry in varmap table + print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL BE"//& + " REPLACED WITH CLIMO. SET A FILL "// & + "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." + dummy2d_8(:,:) = 0.0 endif + else +! print*,'hice ', maxval(gfld%fld),minval(gfld%fld) + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) endif - if(maxval(dummy2d) > 2.0) dummy2d = dummy2d / 100.0_esmf_kind_r4 - print*,'vfrac min',maxval(dummy2d),minval(dummy2d) - endif + endif - print*,"- CALL FieldScatter FOR INPUT GRID MIN VEG GREENNESS." - call ESMF_FieldScatter(min_veg_greenness_input_grid,real(dummy2d,esmf_kind_r8), rootpet=0, rc=rc) + print*,"- CALL FieldScatter FOR INPUT GRID SEAICE DEPTH." + call ESMF_FieldScatter(seaice_depth_input_grid,dummy2d_8, rootpet=0, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& call error_handler("IN FieldScatter", rc) - + if (localpet == 0) then - print*,"- READ MAX VEG FRACTION." - vname="vfrac_max" - slev=":surface:" + + print*,"- READ TPRCP." + vname="tprcp" + slev=":surface:" call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & - loc=varnum) - - vname=":VEG:" - rc= grb2_inq(the_file, inv_file, vname,slev,'n=1107:',data2=dummy2d) - if (rc <=0) then - rc= grb2_inq(the_file, inv_file, vname,slev,'n=1103:',data2=dummy2d) - if (rc <=0) then - rc= grb2_inq(the_file, inv_file, vname,slev,'n=1153:',data2=dummy2d) - if (rc <= 0) call error_handler("COULD NOT FIND MAX VEGETATION FRACTION IN FILE. & - PLEASE SET MINMAX_VGFRC_FROM_CLIMO=.TRUE. . EXITING",rc) - endif + loc=varnum) + +! No test data contained this field. So could not test with g2 library. + rc = 1 + if (rc /= 0) then + call handle_grib_error(vname, slev ,method,value,varnum,rc, var8=dummy2d_8) + if (rc==1) then ! missing_var_method == skip or no entry in varmap table + print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL NOT"//& + " BE WRITTEN TO THE INPUT FILE. SET A FILL "// & + "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." + dummy2d_8 = 0.0 + endif endif - if(maxval(dummy2d) > 2.0) dummy2d = dummy2d / 100.0_esmf_kind_r4 - print*,'vfrac max',maxval(dummy2d),minval(dummy2d) + print*,'tprcp ',maxval(dummy2d_8),minval(dummy2d_8) - endif !localpet==0 + endif ! tprcp - print*,"- CALL FieldScatter FOR INPUT GRID MAX VEG GREENNESS." - call ESMF_FieldScatter(max_veg_greenness_input_grid,real(dummy2d,esmf_kind_r8),rootpet=0, rc=rc) + print*,"- CALL FieldScatter FOR INPUT GRID TPRCP." + call ESMF_FieldScatter(tprcp_input_grid,dummy2d_8, rootpet=0, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& call error_handler("IN FieldScatter", rc) - endif !minmax_vgfrc_from_climo - if (.not. lai_from_climo) then if (localpet == 0) then - print*,"- READ LAI." - vname="lai" - slev=":surface:" + + print*,"- READ FFMM." + vname="ffmm" + slev=":surface:" call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & - loc=varnum) - vname=":var0_7_198:" - rc= grb2_inq(the_file, inv_file, vname,slev,':n=1108:',data2=dummy2d) - if (rc <=0) then - rc= grb2_inq(the_file, inv_file, vname,slev,':n=1104:',data2=dummy2d) - if (rc <=0) then - rc= grb2_inq(the_file, inv_file, vname,slev,':n=1154:',data2=dummy2d) - if (rc <= 0) call error_handler("COULD NOT FIND LAI IN FILE. & - PLEASE SET LAI_FROM_CLIMO=.TRUE. . EXITING",rc) + loc=varnum) + +! No sample data contained this field, so could not test g2lib. + rc = 1 + if (rc /= 0) then + call handle_grib_error(vname, slev ,method,value,varnum,rc, var8=dummy2d_8) + if (rc==1) then ! missing_var_method == skip or no entry in varmap table + print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL NOT"//& + " BE WRITTEN TO THE INPUT FILE. SET A FILL "// & + "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." + dummy2d_8(:,:) = 0.0 endif endif - print*,'lai',maxval(dummy2d),minval(dummy2d) - endif !localpet==0 + print*,'ffmm ',maxval(dummy2d_8),minval(dummy2d_8) - print*,"- CALL FieldScatter FOR INPUT GRID LAI." - call ESMF_FieldScatter(lai_input_grid,real(dummy2d,esmf_kind_r8),rootpet=0, rc=rc) + endif ! ffmm + + print*,"- CALL FieldScatter FOR INPUT GRID FFMM" + call ESMF_FieldScatter(ffmm_input_grid,dummy2d_8, rootpet=0, rc=rc) if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& call error_handler("IN FieldScatter", rc) - - endif - if (localpet == 0) then - print*,"- READ SEAICE DEPTH." - vname="hice" - slev=":surface:" - call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & - loc=varnum) - vname=":ICETK:" - rc= grb2_inq(the_file, inv_file, vname,slev, data2=dummy2d) - if (rc <= 0) then - call handle_grib_error(vname, slev ,method,value,varnum,rc, var= dummy2d) - if (rc==1) then ! missing_var_method == skip or no entry in varmap table - print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL BE"//& - " REPLACED WITH CLIMO. SET A FILL "// & - "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." - dummy2d(:,:) = 0.0_esmf_kind_r4 - endif - endif - dummy2d_8= real(dummy2d,esmf_kind_r8) - print*,'hice ',maxval(dummy2d),minval(dummy2d) - - endif - - print*,"- CALL FieldScatter FOR INPUT GRID SEAICE DEPTH." - call ESMF_FieldScatter(seaice_depth_input_grid,dummy2d_8, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) - if (localpet == 0) then - print*,"- READ TPRCP." - vname="tprcp" - slev=":surface:" - call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & - loc=varnum) - vname=":TPRCP:" - rc= grb2_inq(the_file, inv_file, vname,slev, data2=dummy2d) - if (rc <= 0) then - call handle_grib_error(vname, slev ,method,value,varnum,rc, var= dummy2d) - if (rc==1) then ! missing_var_method == skip or no entry in varmap table - print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL NOT"//& - " BE WRITTEN TO THE INPUT FILE. SET A FILL "// & - "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." - dummy2d(:,:) = 0.0_esmf_kind_r4 - endif - endif - dummy2d_8= real(dummy2d,esmf_kind_r8) - print*,'tprcp ',maxval(dummy2d),minval(dummy2d) - endif + if (localpet == 0) then - print*,"- CALL FieldScatter FOR INPUT GRID TPRCP." - call ESMF_FieldScatter(tprcp_input_grid,dummy2d_8, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) - - if (localpet == 0) then - print*,"- READ FFMM." - vname="ffmm" - slev=":surface:" - call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & + print*,"- READ USTAR." + vname="fricv" + slev=":surface:" + call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & loc=varnum) - vname=":FFMM:" - rc= grb2_inq(the_file, inv_file, vname,slev, data2=dummy2d) - if (rc <= 0) then - call handle_grib_error(vname, slev ,method,value,varnum,rc, var= dummy2d) - if (rc==1) then ! missing_var_method == skip or no entry in varmap table - print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL NOT"//& - " BE WRITTEN TO THE INPUT FILE. SET A FILL "// & - "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." - dummy2d(:,:) = 0.0_esmf_kind_r4 - endif - endif - dummy2d_8= real(dummy2d,esmf_kind_r8) - print*,'ffmm ',maxval(dummy2d),minval(dummy2d) - endif - print*,"- CALL FieldScatter FOR INPUT GRID FFMM" - call ESMF_FieldScatter(ffmm_input_grid,dummy2d_8, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) - - if (localpet == 0) then - print*,"- READ USTAR." - vname="fricv" - slev=":surface:" - call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & - loc=varnum) - vname=":FRICV:" - rc= grb2_inq(the_file, inv_file, vname,slev, data2=dummy2d) - if (rc <= 0) then - call handle_grib_error(vname, slev ,method,value,varnum,rc, var= dummy2d) - if (rc==1) then ! missing_var_method == skip or no entry in varmap table - print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL "//& + jdisc = 0 ! Search for discipline - meteorological products + j = 0 ! Search at beginning of file. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template Sec4. + jpdt(1) = 2 ! Sec4/oct 10 - parameter category - momentum + jpdt(2) = 30 ! Sec4/oct 11 - parameter number - friction velocity + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + if (rc /= 0) then + jpdt(2) = 197 ! oct 11 - param number - friction vel. + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + endif + + if (rc == 0) then +! print*,'fricv ', maxval(gfld%fld),minval(gfld%fld) + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + else + call handle_grib_error(vname, slev ,method,value,varnum,rc, var8=dummy2d_8) + if (rc==1) then ! missing_var_method == skip or no entry in varmap table + print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL "//& "REPLACED WITH CLIMO. SET A FILL "// & "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." - dummy2d(:,:) = 0.0_esmf_kind_r4 - endif - endif - dummy2d_8= real(dummy2d,esmf_kind_r8) - print*,'fricv ',maxval(dummy2d),minval(dummy2d) - endif + dummy2d_8(:,:) = 0.0 + endif + endif - print*,"- CALL FieldScatter FOR INPUT GRID USTAR" - call ESMF_FieldScatter(ustar_input_grid,dummy2d_8, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + endif ! ustar - if (localpet == 0) then - print*,"- READ F10M." - vname="f10m" - slev=":10 m above ground:" - call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & + print*,"- CALL FieldScatter FOR INPUT GRID USTAR" + call ESMF_FieldScatter(ustar_input_grid,dummy2d_8, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + if (localpet == 0) then + + print*,"- READ F10M." + vname="f10m" + slev=":10 m above ground:" + call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & loc=varnum) - vname=":F10M:" - rc= grb2_inq(the_file, inv_file, vname,slev, data2=dummy2d) - if (rc <= 0) then - call handle_grib_error(vname, slev ,method,value,varnum,rc, var= dummy2d) - if (rc==1) then ! missing_var_method == skip or no entry in varmap table - print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL NOT"//& + + rc = -1 ! None of the test cases have this record. Can't test with g2lib. + if (rc /= 0) then + call handle_grib_error(vname, slev ,method,value,varnum,rc, var8=dummy2d_8) + if (rc==1) then ! missing_var_method == skip or no entry in varmap table + print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL NOT"//& " BE WRITTEN TO THE INPUT FILE. SET A FILL "// & "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." - dummy2d(:,:) = 0.0_esmf_kind_r4 - endif - endif - dummy2d_8= real(dummy2d,esmf_kind_r8) - print*,'f10m ',maxval(dummy2d),minval(dummy2d) - endif + dummy2d_8(:,:) = 0.0 + endif + endif + print*,'f10m ',maxval(dummy2d_8),minval(dummy2d_8) - print*,"- CALL FieldScatter FOR INPUT GRID F10M." - call ESMF_FieldScatter(f10m_input_grid,dummy2d_8, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + endif - if (localpet == 0) then - print*,"- READ CANOPY MOISTURE CONTENT." - vname="cnwat" - slev=":surface:" - call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & + print*,"- CALL FieldScatter FOR INPUT GRID F10M." + call ESMF_FieldScatter(f10m_input_grid,dummy2d_8, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + if (localpet == 0) then + + print*,"- READ CANOPY MOISTURE CONTENT." + vname="cnwat" + slev=":surface:" + call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & loc=varnum) - vname=":CNWAT:" - rc= grb2_inq(the_file, inv_file, vname,slev, data2=dummy2d) - if (rc <= 0) then - call handle_grib_error(vname, slev ,method,value,varnum,rc, var= dummy2d) - if (rc==1) then ! missing_var_method == skip or no entry in varmap table - print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL"//& + + jdisc = 2 ! Search for discipline - land products + j = 0 ! Search from beginning of file + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template Sec4. + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - veg/biomass + jpdt(2) = 13 ! Sec4/oct 11 - parameter number - canopy water + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0 ) then + jpdt(2) = 196 ! Sec4/oct 11 - param number - canopy water + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + endif + + if (rc == 0 ) then + print*,'cnwat ', maxval(gfld%fld),minval(gfld%fld) + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + call check_cnwat(dummy2d_8) + else + call handle_grib_error(vname, slev ,method,value,varnum,rc, var8=dummy2d_8) + if (rc==1) then ! missing_var_method == skip or no entry in varmap table + print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL"//& " REPLACED WITH CLIMO. SET A FILL "// & "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." - dummy2d(:,:) = 0.0_esmf_kind_r4 - endif - endif - call check_cnwat(dummy2d) - dummy2d_8= real(dummy2d,esmf_kind_r8) - print*,'cnwat ',maxval(dummy2d),minval(dummy2d) - endif + dummy2d_8 = 0.0 + endif + endif - print*,"- CALL FieldScatter FOR INPUT GRID CANOPY MOISTURE CONTENT." - call ESMF_FieldScatter(canopy_mc_input_grid,dummy2d_8, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + endif - if (localpet == 0) then - print*,"- READ Z0." - vname="sfcr" - slev=":surface:" - call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & + print*,"- CALL FieldScatter FOR INPUT GRID CANOPY MOISTURE CONTENT." + call ESMF_FieldScatter(canopy_mc_input_grid,dummy2d_8, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + if (localpet == 0) then + + print*,"- READ Z0." + vname="sfcr" + slev=":surface:" + call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & loc=varnum) - vname=":SFCR:" - rc= grb2_inq(the_file, inv_file, vname,slev, data2=dummy2d) - if (rc <= 0) then - call handle_grib_error(vname, slev ,method,value,varnum,rc, var= dummy2d) - if (rc==1) then ! missing_var_method == skip or no entry in varmap table - print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL BE"//& + + jdisc = 2 ! Search for discipline - land products + j = 0 ! Search from beginning of file. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template Sec4. + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - veg/biomass + jpdt(2) = 1 ! Sec4/oct 11 - parameter number - surface roughness + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0 ) then + call handle_grib_error(vname, slev ,method,value,varnum,rc, var8= dummy2d_8) + if (rc==1) then ! missing_var_method == skip or no entry in varmap table + print*, "WARNING: "//trim(vname)//" NOT AVAILABLE IN FILE. THIS FIELD WILL BE"//& " REPLACED WITH CLIMO. SET A FILL "// & "VALUE IN THE VARMAP TABLE IF THIS IS NOT DESIRABLE." - dummy2d(:,:) = 0.0_esmf_kind_r4 - endif - else - ! Grib files have z0 (m), but fv3 expects z0(cm) - dummy2d(:,:) = dummy2d(:,:)*10.0 - endif - dummy2d_8= real(dummy2d,esmf_kind_r8) - print*,'sfcr ',maxval(dummy2d),minval(dummy2d) - - endif + dummy2d_8(:,:) = 0.0 + endif + else + gfld%fld = gfld%fld * 10.0 ! Grib files have z0 (m), but fv3 expects z0(cm) +! print*,'sfcr ', maxval(gfld%fld),minval(gfld%fld) + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) + endif - print*,"- CALL FieldScatter FOR INPUT GRID Z0." - call ESMF_FieldScatter(z0_input_grid,dummy2d_8, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) - + endif + + print*,"- CALL FieldScatter FOR INPUT GRID Z0." + call ESMF_FieldScatter(z0_input_grid,dummy2d_8, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) - if (localpet == 0) then - print*,"- READ LIQUID SOIL MOISTURE." - vname = "soill" - vname_file = ":SOILL:" - call read_grib_soil(the_file,inv_file,vname,vname_file,dummy3d,rc) !!! NEEDTO HANDLE - !!! SOIL LEVELS - print*,'soill ',maxval(dummy3d),minval(dummy3d) - endif + if (localpet == 0) then + print*,"- READ LIQUID SOIL MOISTURE." + vname = "soill" + vname_file = ":SOILL:" + call read_grib_soil(vname,vname_file,lugb, dummy3d) !!! NEED TO HANDLE + !!! SOIL LEVELS + endif - print*,"- CALL FieldScatter FOR INPUT LIQUID SOIL MOISTURE." - call ESMF_FieldScatter(soilm_liq_input_grid, dummy3d, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + print*,"- CALL FieldScatter FOR INPUT LIQUID SOIL MOISTURE." + call ESMF_FieldScatter(soilm_liq_input_grid, dummy3d, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) - if (localpet == 0) then - print*,"- READ TOTAL SOIL MOISTURE." - vname = "soilw" - !vname_file = "var2_2_1_7_0_192" !Some files don't recognize this as soilw,so use - vname_file = "var2_2_1_" ! the var number instead - call read_grib_soil(the_file,inv_file,vname,vname_file,dummy3d,rc) - print*,'soilm ',maxval(dummy3d),minval(dummy3d) - endif + if (localpet == 0) then + print*,"- READ TOTAL SOIL MOISTURE." + vname = "soilw" + vname_file = "var2_2_1_" ! the var number instead + call read_grib_soil(vname,vname_file,lugb,dummy3d) + endif - print*,"- CALL FieldScatter FOR INPUT TOTAL SOIL MOISTURE." - call ESMF_FieldScatter(soilm_tot_input_grid, dummy3d, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + print*,"- CALL FieldScatter FOR INPUT TOTAL SOIL MOISTURE." + call ESMF_FieldScatter(soilm_tot_input_grid, dummy3d, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) !---------------------------------------------------------------------------------------- ! Vegetation type is not available in some files. However, it is needed to identify @@ -5432,75 +6054,82 @@ subroutine read_input_sfc_grib2_file(localpet) ! '1'. Use this flag as a temporary solution. !---------------------------------------------------------------------------------------- - print*, "- CALL FieldGather for INPUT SOIL TYPE." - call ESMF_FieldGather(soil_type_input_grid, dummy2d_82, 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 - print*,"- READ VEG TYPE." - vname="vtype" - slev=":surface:" - call get_var_cond(vname,this_miss_var_method=method, this_miss_var_value=value, & - loc=varnum) - !Note: sometimes the grib files don't have this one named. Searching for this string - ! ensures that the data is found when it exists - - vname="var2_2" - rc= grb2_inq(the_file, inv_file, vname,"_0_198:",slev,' hour fcst:', data2=dummy2d) - if (rc <= 0) then - rc= grb2_inq(the_file, inv_file, vname,"_0_198:",slev,':anl:', data2=dummy2d) - if (rc <= 0) then + print*, "- CALL FieldGather for INPUT SOIL TYPE." + call ESMF_FieldGather(soil_type_input_grid, dummy2d_82, 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 + + print*,"- READ VEG TYPE." + + jdisc = 2 ! Search for discipline - land products + j = 0 ! Search from beginning of file. + jpdtn = 0 ! Search for product def template number 0 - anl or fcst. + jpdt = -9999 ! Initialize array of values in product definition template Sec4. + jpdt(1) = 0 ! Sec4/oct 10 - parameter category - veg/biomass + jpdt(2) = 198 ! Sec4/oct 11 - parameter number - vegetation type + jpdt(10) = 1 ! Sec4/oct 23 - type of level - ground surface + unpack=.true. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc) + + if (rc /= 0 ) then if (.not. vgtyp_from_climo) then call error_handler("COULD NOT FIND VEGETATION TYPE IN FILE. PLEASE SET VGTYP_FROM_CLIMO=.TRUE. . EXITING", rc) - else - do j = 1, j_input - do i = 1, i_input - dummy2d(i,j) = 0.0_esmf_kind_r4 - if(slmsk_save(i,j) == 1 .and. dummy3d(i,j,1) > 0.99) & - dummy2d(i,j) = real(veg_type_landice_input,esmf_kind_r4) - enddo - enddo - endif ! replace_vgtyp - endif !not find :anl: - endif !not find hour fcst: - - if (trim(external_model) .ne. "GFS") then - do j = 1, j_input - do i = 1,i_input - if (dummy2d(i,j) == 15.0_esmf_kind_r4 .and. slmsk_save(i,j) == 1) then - if (dummy3d(i,j,1) < 0.6) then - dummy2d(i,j) = real(veg_type_landice_input,esmf_kind_r4) - elseif (dummy3d(i,j,1) > 0.99) then - slmsk_save(i,j) = 0 - dummy2d(i,j) = 0.0_esmf_kind_r4 - dummy2d_82(i,j) = 0.0_esmf_kind_r8 + else ! Set input veg type at land ice from soil moisture flag (1.0). + do j = 1, j_input + do i = 1, i_input + dummy2d_8(i,j) = 0.0 + if(slmsk_save(i,j) == 1 .and. dummy3d(i,j,1) > 0.99) & ! land ice indicated by + ! soil moisture flag of '1'. + dummy2d_8(i,j) = real(veg_type_landice_input,esmf_kind_r8) + enddo + enddo endif - elseif (dummy2d(i,j) == 17.0_esmf_kind_r4 .and. slmsk_save(i,j)==0) then - dummy2d(i,j) = 0.0_esmf_kind_r4 + else ! found vtype in file. + dummy2d_8 = reshape(gfld%fld , (/i_input,j_input/)) endif - enddo - enddo - endif - dummy2d_8= real(dummy2d,esmf_kind_r8) - print*,'vgtyp ',maxval(dummy2d),minval(dummy2d) - endif !localpet - deallocate(dummy2d) - print*,"- CALL FieldScatter FOR INPUT VEG TYPE." - call ESMF_FieldScatter(veg_type_input_grid, dummy2d_8, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) - print*,"- CALL FieldScatter FOR INPUT SOIL TYPE." - call ESMF_FieldScatter(soil_type_input_grid, dummy2d_82, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + if (trim(external_model) .ne. "GFS") then + do j = 1, j_input + do i = 1,i_input + if (dummy2d_8(i,j) == 15.0_esmf_kind_r8 .and. slmsk_save(i,j) == 1) then + if (dummy3d(i,j,1) < 0.6) then + dummy2d_8(i,j) = real(veg_type_landice_input,esmf_kind_r8) + elseif (dummy3d(i,j,1) > 0.99) then + slmsk_save(i,j) = 0 + dummy2d_8(i,j) = 0.0_esmf_kind_r8 + dummy2d_82(i,j) = 0.0_esmf_kind_r8 + endif + elseif (dummy2d_8(i,j) == 17.0_esmf_kind_r8 .and. slmsk_save(i,j)==0) then + dummy2d_8(i,j) = 0.0_esmf_kind_r8 + endif + enddo + enddo + endif - deallocate(dummy2d_82) +! print*,'vgtyp ',maxval(dummy2d_8),minval(dummy2d_8) - print*,"- CALL FieldScatter FOR INPUT LANDSEA MASK." - call ESMF_FieldScatter(landsea_mask_input_grid,real(slmsk_save,esmf_kind_r8),rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + endif ! read veg type + + print*,"- CALL FieldScatter FOR INPUT VEG TYPE." + call ESMF_FieldScatter(veg_type_input_grid, dummy2d_8, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + print*,"- CALL FieldScatter FOR INPUT SOIL TYPE." + call ESMF_FieldScatter(soil_type_input_grid, dummy2d_82, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) + + deallocate(dummy2d_82) + + print*,"- CALL FieldScatter FOR INPUT LANDSEA MASK." + call ESMF_FieldScatter(landsea_mask_input_grid,real(slmsk_save,esmf_kind_r8),rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) !--------------------------------------------------------------------------------- ! At open water (slmsk==0), the soil temperature array is not used and set @@ -5509,27 +6138,27 @@ subroutine read_input_sfc_grib2_file(localpet) ! in the grib data, so set to a default value. !--------------------------------------------------------------------------------- - if (localpet == 0) then - print*,"- READ SOIL TEMPERATURE." - vname = "soilt" - vname_file = ":TSOIL:" - call read_grib_soil(the_file,inv_file,vname,vname_file,dummy3d,rc) - call check_soilt(dummy3d,slmsk_save,tsk_save) - print*,'soilt ',maxval(dummy3d),minval(dummy3d) - - deallocate(tsk_save) - endif + if (localpet == 0) then + print*,"- READ SOIL TEMPERATURE." + vname = "soilt" + vname_file = ":TSOIL:" + call read_grib_soil(vname,vname_file,lugb,dummy3d) + call check_soilt(dummy3d,slmsk_save,tsk_save) + deallocate(tsk_save) + endif - deallocate(slmsk_save) + deallocate(slmsk_save) - print*,"- CALL FieldScatter FOR INPUT SOIL TEMPERATURE." - call ESMF_FieldScatter(soil_temp_input_grid, dummy3d, rootpet=0, rc=rc) - if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& - call error_handler("IN FieldScatter", rc) + print*,"- CALL FieldScatter FOR INPUT SOIL TEMPERATURE." + call ESMF_FieldScatter(soil_temp_input_grid, dummy3d, rootpet=0, rc=rc) + if(ESMF_logFoundError(rcToCheck=rc,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__))& + call error_handler("IN FieldScatter", rc) - deallocate(dummy3d) - deallocate(dummy2d_8) + deallocate(dummy3d) + deallocate(dummy2d_8) + if (localpet == 0) call baclose(lugb, rc) + end subroutine read_input_sfc_grib2_file !> Read nst data from these netcdf formatted fv3 files: tiled history, @@ -6137,39 +6766,47 @@ END SUBROUTINE READ_FV3_GRID_DATA_NETCDF !> Read winds from a grib2 file. Rotate winds !! to be earth relative if necessary. !! -!! @param [in] file grib2 file to be read -!! @param [in] inv grib2 inventory file !! @param [inout] u u-component wind !! @param [inout] v v-component wind !! @param[in] localpet ESMF local persistent execution thread +!! @param[in] isnative When true, data on hybrid levels. Otherwise +!! data is on isobaric levels. +!! @param[in] rlevs Array of atmospheric level values +!! @param[in] lugb Logical unit number of GRIB2 file. !! @author Larissa Reames - subroutine read_winds(file,inv,u,v,localpet) + subroutine read_winds(u,v,localpet,isnative,rlevs,lugb) + + use grib_mod + use program_setup, only : get_var_cond - use wgrib2api - use netcdf - use program_setup, only : get_var_cond, fix_dir_input_grid - use model_grid, only : input_grid_type implicit none - character(len=250), intent(in) :: file - character(len=10), intent(in) :: inv - integer, intent(in) :: localpet - real(esmf_kind_r8), intent(inout), allocatable :: u(:,:,:),v(:,:,:) + integer, intent(in) :: localpet, lugb + + logical, intent(in) :: isnative + + real(esmf_kind_r8), intent(inout), allocatable :: u(:,:,:),v(:,:,:) + real(esmf_kind_r8), intent(in), dimension(lev_input) :: rlevs real(esmf_kind_r4), dimension(i_input,j_input) :: alpha real(esmf_kind_r8), dimension(i_input,j_input) :: lon, lat real(esmf_kind_r4), allocatable :: u_tmp(:,:),v_tmp(:,:) + real(esmf_kind_r8), allocatable :: dum2d(:,:) real(esmf_kind_r4), dimension(i_input,j_input) :: ws,wd real(esmf_kind_r4) :: value_u, value_v,lov,latin1,latin2 real(esmf_kind_r8) :: d2r - integer :: varnum_u, varnum_v, vlev, & !ncid, id_var, & - error, iret, istr + integer :: varnum_u, varnum_v, vlev, & + error, iret + integer :: j, k, lugi, jgdtn, jpdtn + integer :: jdisc, jids(200), jgdt(200), jpdt(200) character(len=20) :: vname character(len=50) :: method_u, method_v - character(len=250) :: file_coord - character(len=10000) :: temp_msg + + logical :: unpack + + type(gribfield) :: gfld d2r=acos(-1.0_esmf_kind_r8) / 180.0_esmf_kind_r8 if (localpet==0) then @@ -6180,8 +6817,6 @@ subroutine read_winds(file,inv,u,v,localpet) allocate(v(0,0,0)) endif - file_coord = trim(fix_dir_input_grid)//"/latlon_grid3.32769.nc" - vname = "u" call get_var_cond(vname,this_miss_var_method=method_u, this_miss_var_value=value_u, & loc=varnum_u) @@ -6189,90 +6824,107 @@ subroutine read_winds(file,inv,u,v,localpet) call get_var_cond(vname,this_miss_var_method=method_v, this_miss_var_value=value_v, & loc=varnum_v) - if (trim(input_grid_type)=="rotated_latlon") then - print*,"- CALL FieldGather FOR INPUT GRID LONGITUDE" - call ESMF_FieldGather(longitude_input_grid, lon, rootPet=0, tile=1, rc=error) - if(ESMF_logFoundError(rcToCheck=error,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & - call error_handler("IN FieldGather", error) - print*,"- CALL FieldGather FOR INPUT GRID LATITUDE" - call ESMF_FieldGather(latitude_input_grid, lat, rootPet=0, tile=1, rc=error) - if(ESMF_logFoundError(rcToCheck=error,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & + print*,"- CALL FieldGather FOR INPUT GRID LONGITUDE" + call ESMF_FieldGather(longitude_input_grid, lon, rootPet=0, tile=1, rc=error) + if(ESMF_logFoundError(rcToCheck=error,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldGather", error) - if (localpet==0) then - print*,"- CALCULATE ROTATION ANGLE FOR ROTATED_LATLON INPUT GRID" - error = grb2_inq(file, inv,grid_desc=temp_msg) - !1:0:grid_template=32769:winds(grid): - ! I am not an Arakawa E-grid. - ! I am rotated but have no rotation angle. - ! I am staggered. What am I? - ! (953 x 834) units 1e-06 input WE:SN output WE:SN res 56 - ! lat0 -10.590603 lat-center 54.000000 dlat 121.813000 - ! lon0 220.914154 lon-center 254.000000 dlon 121.813000 #points=794802 - - istr = index(temp_msg, "lat-center ") + len("lat_center ") - read(temp_msg(istr:istr+9),"(F8.5)") latin1 - istr = index(temp_msg, "lon-center ") + len("lon-center ") - read(temp_msg(istr:istr+10),"(F9.6)") lov - - print*, "- CALL CALCALPHA_ROTLATLON with center lat,lon = ",latin1,lov - call calcalpha_rotlatlon(lat,lon,latin1,lov,alpha) - print*, " alpha min/max = ",MINVAL(alpha),MAXVAL(alpha) - endif - elseif (trim(input_grid_type) == "lambert") then - !# NG this has been edited to correctly calculate gridrot for Lambert grids - ! Previously was incorrectly using polar-stereographic formation - print*,"- CALL FieldGather FOR INPUT GRID LONGITUDE" - call ESMF_FieldGather(longitude_input_grid, lon, rootPet=0, tile=1, rc=error) - if(ESMF_logFoundError(rcToCheck=error,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & + print*,"- CALL FieldGather FOR INPUT GRID LATITUDE" + call ESMF_FieldGather(latitude_input_grid, lat, rootPet=0, tile=1, rc=error) + if(ESMF_logFoundError(rcToCheck=error,msg=ESMF_LOGERR_PASSTHRU,line=__LINE__,file=__FILE__)) & call error_handler("IN FieldGather", error) - if (localpet==0) then - error = grb2_inq(file, inv,grid_desc=temp_msg) - !1:0:grid_template=30:winds(grid): - ! Lambert Conformal: (1799 x 1059) input WE:SN output WE:SN res 8 - ! Lat1 21.138123 Lon1 237.280472 LoV 262.500000 - ! LatD 38.500000 Latin1 38.500000 Latin2 38.500000 - ! LatSP 0.000000 LonSP 0.000000 - ! North Pole (1799 x 1059) Dx 3000.000000 m Dy 3000.000000 m mode 8 - - istr = index(temp_msg, "LoV ") + len("LoV ") - read(temp_msg(istr:istr+10),"(F9.6)") lov - istr = index(temp_msg, "Latin1 ") + len("Latin1 ") - read(temp_msg(istr:istr+9),"(F8.5)") latin1 - istr = index(temp_msg, "Latin2 ") + len("Latin2 ") - read(temp_msg(istr:istr+9),"(F8.5)") latin2 + if (localpet==0) then + + lugi = 0 ! index file unit number + jdisc = 0 ! search for discipline - meteorological products + j = 0 ! search at beginning of file. + jpdt = -9999 ! array of values in product definition template, set to wildcard + jids = -9999 ! array of values in identification section, set to wildcard + jgdt = -9999 ! array of values in grid definition template, set to wildcard + jgdtn = -1 ! search for any grid definition number. + jpdtn = 0 ! search for product def template number 0 - anl or fcst. + unpack=.false. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret /= 0) call error_handler("ERROR READING GRIB2 FILE.", iret) + + if (gfld%igdtnum == 32769) then ! grid definition template number - rotated lat/lon grid + + latin1 = float(gfld%igdtmpl(15))/1.0E6 + lov = float(gfld%igdtmpl(16))/1.0E6 + + print*, "- CALL CALCALPHA_ROTLATLON with center lat,lon = ",latin1,lov + call calcalpha_rotlatlon(lat,lon,latin1,lov,alpha) + + elseif (gfld%igdtnum == 30) then ! grid definition template number - lambert conformal grid. + + lov = float(gfld%igdtmpl(14))/1.0E6 + latin1 = float(gfld%igdtmpl(19))/1.0E6 + latin2 = float(gfld%igdtmpl(20))/1.0E6 print*, "- CALL GRIDROT for LC grid with lov,latin1/2 = ",lov,latin1,latin2 call gridrot(lov,latin1,latin2,lon,alpha) - print*, " alpha min/max = ",MINVAL(alpha),MAXVAL(alpha) + endif - endif - if (localpet==0) then + if (isnative) then + jpdt(10) = 105 ! Sec4/oct 23 - type of level - hybrid + else + jpdt(10) = 100 ! Sec4/oct 23 - type of level - isobaric + endif + + unpack=.true. + + allocate(dum2d(i_input,j_input)) + allocate(u_tmp(i_input,j_input)) + allocate(v_tmp(i_input,j_input)) + do vlev = 1, lev_input vname = ":UGRD:" - iret = grb2_inq(file,inv,vname,slevs(vlev),data2=u_tmp) - if (iret <= 0) then + + jpdt(1) = 2 ! Sec4/oct 10 - parameter category - momentum + jpdt(2) = 2 ! Sec4/oct 11 - parameter number - u-wind + jpdt(12) = nint(rlevs(vlev)) ! Sect4/octs 25-28 - scaled value of fixed surface. + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret /= 0) then call handle_grib_error(vname, slevs(vlev),method_u,value_u,varnum_u,iret,var=u_tmp) if (iret==1) then ! missing_var_method == skip call error_handler("READING IN U AT LEVEL "//trim(slevs(vlev))//". SET A FILL "// & "VALUE IN THE VARMAP TABLE IF THIS ERROR IS NOT DESIRABLE.",iret) endif + else + dum2d = reshape(gfld%fld, (/i_input,j_input/) ) + u_tmp(:,:) = dum2d endif vname = ":VGRD:" - iret = grb2_inq(file,inv,vname,slevs(vlev),data2=v_tmp) - if (iret <= 0) then + + jpdt(2) = 3 ! Sec4/oct 11 - parameter number - v-wind + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, iret) + + if (iret /= 0) then call handle_grib_error(vname, slevs(vlev),method_v,value_v,varnum_v,iret,var=v_tmp) if (iret==1) then ! missing_var_method == skip call error_handler("READING IN V AT LEVEL "//trim(slevs(vlev))//". SET A FILL "// & - "VALUE IN THE VARMAP TABLE IF THIS ERROR IS NOT DESIRABLE.",iret) + "VALUE IN THE VARMAP TABLE IF THIS ERROR IS NOT DESIRABLE.",iret) endif - endif + else + dum2d = reshape(gfld%fld, (/i_input,j_input/) ) + v_tmp(:,:) = dum2d + endif - if (trim(input_grid_type) == "latlon") then + deallocate(dum2d) + + if (gfld%igdtnum == 0) then ! grid definition template number - lat/lon grid if (external_model == 'UKMET') then u(:,:,vlev) = u_tmp v(:,:,vlev) = (v_tmp(:,2:jp1_input) + v_tmp(:,1:j_input))/2 @@ -6280,7 +6932,7 @@ subroutine read_winds(file,inv,u,v,localpet) u(:,:,vlev) = u_tmp v(:,:,vlev) = v_tmp endif - else if (trim(input_grid_type) == "rotated_latlon") then + else if (gfld%igdtnum == 32769) then ! grid definition template number - rotated lat/lon grid ws = sqrt(u_tmp**2 + v_tmp**2) wd = atan2(-u_tmp,-v_tmp) / d2r ! calculate grid-relative wind direction wd = wd + alpha + 180.0 ! Rotate from grid- to earth-relative direction @@ -6498,13 +7150,13 @@ subroutine handle_grib_error(vname,lev,method,value,varnum, iret,var,var8,var3d) read_from_input(varnum) = .false. iret = 1 elseif (trim(method) == "set_to_fill") then - print*, "WARNING: ,", trim(vname), " NOT AVILABLE AT LEVEL ", trim(lev), & + print*, "WARNING: ,", trim(vname), " NOT AVAILABLE AT LEVEL ", trim(lev), & ". SETTING EQUAL TO FILL VALUE OF ", value if(present(var)) var(:,:) = value if(present(var8)) var8(:,:) = value if(present(var3d)) var3d(:,:,:) = value elseif (trim(method) == "set_to_NaN") then - print*, "WARNING: ,", trim(vname), " NOT AVILABLE AT LEVEL ", trim(lev), & + print*, "WARNING: ,", trim(vname), " NOT AVAILABLE AT LEVEL ", trim(lev), & ". SETTING EQUAL TO NaNs" if(present(var)) var(:,:) = ieee_value(var,IEEE_QUIET_NAN) if(present(var8)) var8(:,:) = ieee_value(var8,IEEE_QUIET_NAN) @@ -6527,67 +7179,104 @@ end subroutine handle_grib_error !> Read soil temperature and soil moisture fields from a GRIB2 file. !! -!! @param [in] the_file grib2 file name -!! @param [in] inv_file grib2 inventory file name !! @param [in] vname variable name in varmap table !! @param [in] vname_file variable name in grib2 file +!! @param [in] lugb logical unit number for surface grib2 file !! @param [inout] dummy3d array of soil data -!! @param [out] rc read error status code !! @author George Gayno NCEP/EMC -subroutine read_grib_soil(the_file,inv_file,vname,vname_file,dummy3d,rc) - - use wgrib2api - implicit none + subroutine read_grib_soil(vname, vname_file, lugb, dummy3d) - character(len=*), intent(in) :: the_file, inv_file - character(len=20), intent(in) :: vname,vname_file + use grib_mod + + implicit none - integer, intent(out) :: rc + character(len=20), intent(in) :: vname,vname_file - real(esmf_kind_r8), intent(inout) :: dummy3d(:,:,:) + integer, intent(in) :: lugb + + real(esmf_kind_r8), intent(inout) :: dummy3d(:,:,:) - real(esmf_kind_r4), allocatable :: dummy2d(:,:) - real(esmf_kind_r4) :: value - integer :: varnum,i - character(len=50) :: slevs(lsoil_input) - character(len=50) :: method + character(len=50) :: slevs(lsoil_input) + character(len=50) :: method + + integer :: varnum, i, j, k, rc, rc2 + integer :: jdisc, jgdtn, jpdtn, lugi + integer :: jids(200), jgdt(200), jpdt(200) + integer :: iscale1, iscale2 + + logical :: unpack + + real(esmf_kind_r4), allocatable :: dummy2d(:,:) + real(esmf_kind_r4) :: value + + type(gribfield) :: gfld - allocate(dummy2d(i_input,j_input)) + allocate(dummy2d(i_input,j_input)) - if(lsoil_input == 4) then + if(lsoil_input == 4) then slevs = (/character(24)::':0-0.1 m below ground:', ':0.1-0.4 m below ground:', & ':0.4-1 m below ground:', ':1-2 m below ground:'/) - elseif(lsoil_input == 9) then + elseif(lsoil_input == 9) then slevs = (/character(26)::':0-0 m below ground',':0.01-0.01 m below ground:',':0.04-0.04 m below ground:', & ':0.1-0.1 m below ground:',':0.3-0.3 m below ground:',':0.6-0.6 m below ground:', & ':1-1 m below ground:',':1.6-1.6 m below ground:',':3-3 m below ground:'/) - else + else rc = -1 call error_handler("reading soil levels. File must have 4 or 9 soil levels.", rc) - endif + endif - call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & + call get_var_cond(vname,this_miss_var_method=method,this_miss_var_value=value, & loc=varnum) - do i = 1,lsoil_input - if (vname_file=="var2_2_1_") then - rc = grb2_inq(the_file,inv_file,vname_file,"_0_192:",slevs(i),data2=dummy2d) - else - rc = grb2_inq(the_file,inv_file,vname_file,slevs(i),data2=dummy2d) - endif - if (rc <= 0) then - call handle_grib_error(vname_file, slevs(i),method,value,varnum,rc,var=dummy2d) - if (rc==1 .and. trim(vname) /= "soill") then - ! missing_var_method == skip or no entry in varmap table - call error_handler("READING IN "//trim(vname)//". SET A FILL "// & + + lugi = 0 ! unit number for index file + jdisc = 2 ! search for discipline - land products + j = 0 ! search at beginning of file. + jpdt = -9999 ! array of values in product definition template 4.n + jids = -9999 ! array of values in identification section, set to wildcard + jgdt = -9999 ! array of values in grid definition template 3.m + jgdtn = -1 ! search for any grid definition number. + jpdtn = 0 ! search for product def template number 0 - anl or fcst. + jpdt(1) = 0 ! oct 10 - param cat - veg/biomass + if (trim(vname) == 'soilt') jpdt(2) = 2 ! oct 11 - param number - soil temp + if (trim(vname) == 'soilw') jpdt(2) = 192 ! oct 11 - param number - total soilm + if (trim(vname) == 'soill') then + jpdt(1) = 3 ! oct 10 - soil products + jpdt(2) = 192 ! oct 11 - param number - liquid soilm + endif + jpdt(10) = 106 ! oct 23 - depth below ground + jpdt(13) = 106 ! oct 29 - depth below ground + unpack=.true. + + do i = 1,lsoil_input + + call getgb2(lugb, lugi, j, jdisc, jids, jpdtn, jpdt, jgdtn, jgdt, & + unpack, k, gfld, rc2) + + if (rc2 /= 0) then ! record not found. + call handle_grib_error(vname_file, slevs(i),method,value,varnum,rc,var=dummy2d) + if (rc==1 .and. trim(vname) /= "soill") then + ! missing_var_method == skip or no entry in varmap table + call error_handler("READING IN "//trim(vname)//". SET A FILL "// & "VALUE IN THE VARMAP TABLE IF THIS ERROR IS NOT DESIRABLE.",rc) - elseif (rc==1) then - dummy3d(:,:,:) = 0.0_esmf_kind_r8 - exit - endif - endif + elseif (rc==1) then + dummy3d(:,:,:) = 0.0_esmf_kind_r8 + return + endif + endif + + if (rc2 == 0) then ! record found. + iscale1 = 10 ** gfld%ipdtmpl(11) + iscale2 = 10 ** gfld%ipdtmpl(14) +! print*,'getgb2 top of soil layer in m ', float(gfld%ipdtmpl(12))/float(iscale1) +! print*,'getgb2 bot of soil layer in m ', float(gfld%ipdtmpl(15))/float(iscale2) + dummy2d = reshape(gfld%fld, (/i_input,j_input/) ) + endif - dummy3d(:,:,i) = real(dummy2d,esmf_kind_r8) - end do + j = k + + dummy3d(:,:,i) = real(dummy2d,esmf_kind_r8) + + enddo deallocate(dummy2d) @@ -6776,15 +7465,15 @@ end subroutine check_soilt subroutine check_cnwat(cnwat) implicit none - real(esmf_kind_r4), intent(inout) :: cnwat(i_input,j_input) + real(esmf_kind_r8), intent(inout) :: cnwat(i_input,j_input) - real(esmf_kind_r4) :: max_cnwat = 0.5 + real(esmf_kind_r8) :: max_cnwat = 0.5 integer :: i, j do i = 1,i_input do j = 1,j_input - if (cnwat(i,j) .gt. max_cnwat) cnwat(i,j) = 0.0_esmf_kind_r4 + if (cnwat(i,j) .gt. max_cnwat) cnwat(i,j) = 0.0_esmf_kind_r8 enddo enddo end subroutine check_cnwat diff --git a/sorc/chgres_cube.fd/model_grid.F90 b/sorc/chgres_cube.fd/model_grid.F90 index 028693f35..0cf0257a2 100644 --- a/sorc/chgres_cube.fd/model_grid.F90 +++ b/sorc/chgres_cube.fd/model_grid.F90 @@ -700,8 +700,12 @@ subroutine define_input_grid_gfs_grib2(localpet, npets) longitude(i,:) = real(lon4(i,:),kind=esmf_kind_r8) enddo +! Flip the poles, to be consistent with how the g2lib degribs +! gfs data. + do i = 1, j_input - latitude(:,i) = real(lat4(:,i),kind=esmf_kind_r8) + latitude(:,i) = real(lat4(:,j_input-i+1),kind=esmf_kind_r8) +! if (localpet == 0) print*,'gfs lat ',i,latitude(1,i) enddo deallocate(lat4, lon4) @@ -783,11 +787,11 @@ subroutine define_input_grid_gfs_grib2(localpet, npets) lon_corner_src_ptr(i,j) = longitude(i,1) - (0.5_esmf_kind_r8*deltalon) if (lon_corner_src_ptr(i,j) > 360.0_esmf_kind_r8) lon_corner_src_ptr(i,j) = lon_corner_src_ptr(i,j) - 360.0_esmf_kind_r8 if (j == 1) then - lat_corner_src_ptr(i,j) = -90.0_esmf_kind_r8 + lat_corner_src_ptr(i,j) = +90.0_esmf_kind_r8 cycle endif if (j == jp1_input) then - lat_corner_src_ptr(i,j) = +90.0_esmf_kind_r8 + lat_corner_src_ptr(i,j) = -90.0_esmf_kind_r8 cycle endif lat_corner_src_ptr(i,j) = 0.5_esmf_kind_r8 * (latitude(i,j-1)+ latitude(i,j)) diff --git a/tests/chgres_cube/CMakeLists.txt b/tests/chgres_cube/CMakeLists.txt index adcf0621b..73274ca76 100644 --- a/tests/chgres_cube/CMakeLists.txt +++ b/tests/chgres_cube/CMakeLists.txt @@ -42,6 +42,18 @@ add_executable(ftst_utils ftst_utils.F90) add_test(NAME chgres_cube-ftst_utils COMMAND ftst_utils) target_link_libraries(ftst_utils chgres_cube_lib) +add_executable(ftst_read_atm_grib2 ftst_read_atm_grib2.F90) +target_link_libraries(ftst_read_atm_grib2 chgres_cube_lib) +add_mpi_test(chgres_cube-ftst_read_atm_grib2 + EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/ftst_read_atm_grib2 + NUMPROCS 1 TIMEOUT 60) + +add_executable(ftst_read_sfc_grib2 ftst_read_sfc_grib2.F90) +target_link_libraries(ftst_read_sfc_grib2 chgres_cube_lib) +add_mpi_test(chgres_cube-ftst_read_sfc_grib2 + EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/ftst_read_sfc_grib2 + NUMPROCS 1 TIMEOUT 60) + add_executable(ftst_program_setup ftst_program_setup.F90) target_link_libraries(ftst_program_setup chgres_cube_lib) add_mpi_test(chgres_cube-ftst_program_setup diff --git a/tests/chgres_cube/LSanSuppress.supp b/tests/chgres_cube/LSanSuppress.supp index 7c73079ce..61404b2a9 100644 --- a/tests/chgres_cube/LSanSuppress.supp +++ b/tests/chgres_cube/LSanSuppress.supp @@ -2,4 +2,5 @@ leak:ESMCI leak:ESMC leak:esmc leak:esmf +leak:g2 leak:std::vector diff --git a/tests/chgres_cube/data/files.txt b/tests/chgres_cube/data/files.txt index de82305d7..e214957a4 100644 --- a/tests/chgres_cube/data/files.txt +++ b/tests/chgres_cube/data/files.txt @@ -3,3 +3,4 @@ https://ftp.emc.ncep.noaa.gov/static_files/public/UFS/ufs_utils/unit_tests/chgre https://ftp.emc.ncep.noaa.gov/static_files/public/UFS/ufs_utils/unit_tests/chgres_cube/gfs.v16.atm.history.nc https://ftp.emc.ncep.noaa.gov/static_files/public/UFS/ufs_utils/unit_tests/chgres_cube/gfs.v14.sfc.history.nemsio https://ftp.emc.ncep.noaa.gov/static_files/public/UFS/ufs_utils/unit_tests/chgres_cube/gfs.v15.sfc.history.nemsio +https://ftp.emc.ncep.noaa.gov/static_files/public/UFS/ufs_utils/unit_tests/chgres_cube/gfs.t00z.pgrb2.0p50.f000 diff --git a/tests/chgres_cube/ftst_read_atm_grib2.F90 b/tests/chgres_cube/ftst_read_atm_grib2.F90 new file mode 100644 index 000000000..b9a030974 --- /dev/null +++ b/tests/chgres_cube/ftst_read_atm_grib2.F90 @@ -0,0 +1,256 @@ + program read_atm_grib2 + +! Unit test for the "read_input_atm_grib2_file" +! routine of chgres_cube. +! +! Reads a 0.5-degree GFS GRIB2 file. The data read +! from the file is compared to expected values as +! determined from the 'wgrib2' stand-alone utility. +! +! Author George Gayno + + use esmf + + use input_data, only : read_input_atm_data, & + lev_input, & + levp1_input, & + temp_input_grid, tracers_input_grid, & + dzdt_input_grid, pres_input_grid, & + ps_input_grid, wind_input_grid, & + terrain_input_grid + + use program_setup, only : input_type, data_dir_input_grid, & + grib2_file_input_grid, & + read_varmap, varmap_file, & + num_tracers, num_tracers_input, & + tracers, tracers_input, external_model + + use model_grid, only : input_grid, & + i_input, j_input, & + latitude_input_grid, & + longitude_input_grid + + implicit none + + type(esmf_vm) :: vm + + type(esmf_polekind_flag) :: polekindflag(2) + + integer, parameter :: EXPECTED_LEV_INPUT=31 ! Number of vertical layers. + integer, parameter :: EXPECTED_LEVP1_INPUT=32 ! Number of vertical layer + ! interfaces. + + integer, parameter :: NUM_VALUES=2 ! Number of values compared per record. + + real, parameter :: EPSILON=0.0001 + real, parameter :: EPSILON_SMALL=0.0000001 + + integer :: rc, localpet, n, npets + integer :: i_check(NUM_VALUES), j_check(NUM_VALUES), k_check(NUM_VALUES) + + real(esmf_kind_r8), allocatable :: latitude(:,:) + real(esmf_kind_r8), allocatable :: longitude(:,:) + real(esmf_kind_r8), allocatable :: data_one_tile(:,:) + real(esmf_kind_r8), allocatable :: data3d_one_tile(:,:,:) + real(esmf_kind_r8), allocatable :: data4d_one_tile(:,:,:,:) + + real :: expected_values_tmp(NUM_VALUES) + real :: expected_values_sphum(NUM_VALUES) + real :: expected_values_liq_wat(NUM_VALUES) + real :: expected_values_o3mr(NUM_VALUES) + real :: expected_values_icewat(NUM_VALUES) + real :: expected_values_rainwat(NUM_VALUES) + real :: expected_values_snowwat(NUM_VALUES) + real :: expected_values_graupel(NUM_VALUES) + real :: expected_values_dzdt(NUM_VALUES) + real :: expected_values_pres(NUM_VALUES) + real :: expected_values_ps(NUM_VALUES) + real :: expected_values_terrain(NUM_VALUES) + real :: expected_values_xwind(NUM_VALUES) + real :: expected_values_ywind(NUM_VALUES) + real :: expected_values_zwind(NUM_VALUES) + +! The expected values were determined by the checking +! the input GRIB2 file using stand-alone 'wgrib2'. + + data expected_values_tmp / 300.5728, 262.8000 / ! Temperature + data expected_values_sphum / 0.01659, 0.0 / ! Specific humidity + data expected_values_liq_wat / 0.0, 0.0 / ! Cloud liquid water + data expected_values_o3mr / 6.69e-08, 4.94e-06 / ! Ozone + data expected_values_icewat / 0.0, 0.0 / ! Ice water + data expected_values_rainwat / 0.0, 0.0 / ! Rain water + data expected_values_snowwat / 0.0, 0.0 / ! Snow water + data expected_values_graupel / 0.0, 0.0 / ! Graupel + data expected_values_dzdt / 8.48e-03, 0.0 / ! Vertical velocity + data expected_values_pres / 100000.0, 100.0 / ! 3-d pressure + data expected_values_ps / 100662.9, 100662.9 / ! Surface pressure + data expected_values_terrain / 5.973e-2, 5.973e-2 / ! Terrain height + data expected_values_xwind / -6.3605, 7.3208 / ! x-component wind + data expected_values_ywind / -0.1167, -5.1422 / ! y-component wind + data expected_values_zwind / 0.0, 0.0 / ! z-component wind + + print*,"Starting test of read_atm_grib2_file." + + call mpi_init(rc) + + call ESMF_Initialize(rc=rc) + + call ESMF_VMGetGlobal(vm, rc=rc) + + call ESMF_VMGet(vm, localPet=localpet, petCount=npets, rc=rc) + + external_model="GFS" + input_type="grib2" +!data_dir_input_grid = "/scratch1/NCEPDEV/da/George.Gayno/noscrub/reg_tests/chgres_cube/input_data/gfs.grib2" + data_dir_input_grid = "data/" + grib2_file_input_grid = "gfs.t00z.pgrb2.0p50.f000" + + i_input = 720 + j_input = 361 + + polekindflag(1:2) = ESMF_POLEKIND_MONOPOLE + input_grid = ESMF_GridCreate1PeriDim(minIndex=(/1,1/), & + maxIndex=(/i_input,j_input/), & + polekindflag=polekindflag, & + periodicDim=1, & + poleDim=2, & + coordSys=ESMF_COORDSYS_SPH_DEG, & + regDecomp=(/1,npets/), & + indexflag=ESMF_INDEX_GLOBAL, rc=rc) + + + num_tracers=7 + num_tracers_input=num_tracers + + tracers_input(1)="spfh" + tracers_input(2)="clwmr" + tracers_input(3)="o3mr" + tracers_input(4)="icmr" + tracers_input(5)="rwmr" + tracers_input(6)="snmr" + tracers_input(7)="grle" + + tracers(1)="sphum" + tracers(2)="liq_wat" + tracers(3)="o3mr" + tracers(4)="ice_wat" + tracers(5)="rainwat" + tracers(6)="snowwat" + tracers(7)="graupel" + + varmap_file ="./data/GFSphys_varmap.txt" + call read_varmap + + 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) + +! Using the north pole/greenwich simplifies the comparison +! of u/v winds. + + allocate(latitude(i_input,j_input)) + allocate(longitude(i_input,j_input)) + latitude=90.0 + longitude=0.0 + + call ESMF_FieldScatter(longitude_input_grid, longitude, rootpet=0, rc=rc) + call ESMF_FieldScatter(latitude_input_grid, latitude, rootpet=0, rc=rc) + +! Call the chgres_cube read routine. + + call read_input_atm_data(localpet) + +! Compare what was read to expected values. + + if (lev_input /= EXPECTED_LEV_INPUT) stop 2 + if (levp1_input /= EXPECTED_LEVP1_INPUT) stop 3 + + allocate(data3d_one_tile(i_input,j_input,lev_input)) + allocate(data4d_one_tile(i_input,j_input,lev_input,3)) + allocate(data_one_tile(i_input,j_input)) + +! The i/j/k of the points to be checked. + + i_check(1) = i_input/2 + j_check(1) = 182 + k_check(1) = 1 + + i_check(2) = i_input/2 + j_check(2) = 182 + k_check(2) = lev_input + + call ESMF_FieldGather(temp_input_grid, data3d_one_tile, rootPet=0, rc=rc) + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_tmp(1)) > EPSILON) stop 4 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_tmp(2)) > EPSILON) stop 5 + + do n = 1, num_tracers + call ESMF_FieldGather(tracers_input_grid(n), data3d_one_tile, rootPet=0, rc=rc) + if (trim(tracers(n)) == 'sphum') then + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_sphum(1)) > EPSILON) stop 6 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_sphum(2)) > EPSILON_SMALL) stop 7 + endif + if (trim(tracers(n)) == 'liq_wat') then + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_liq_wat(1)) > EPSILON_SMALL) stop 8 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_liq_wat(2)) > EPSILON_SMALL) stop 9 + endif + if (trim(tracers(n)) == 'o3mr') then + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_o3mr(1)) > EPSILON_SMALL) stop 10 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_o3mr(2)) > EPSILON_SMALL) stop 11 + endif + if (trim(tracers(n)) == 'ice_wat') then + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_icewat(1)) > EPSILON_SMALL) stop 12 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_icewat(2)) > EPSILON_SMALL) stop 13 + endif + if (trim(tracers(n)) == 'rainwat') then + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_rainwat(1)) > EPSILON_SMALL) stop 14 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_rainwat(2)) > EPSILON_SMALL) stop 15 + endif + if (trim(tracers(n)) == 'snowwat') then + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_snowwat(1)) > EPSILON_SMALL) stop 16 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_snowwat(2)) > EPSILON_SMALL) stop 17 + endif + if (trim(tracers(n)) == 'graupel') then + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_graupel(1)) > EPSILON_SMALL) stop 18 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_graupel(2)) > EPSILON_SMALL) stop 19 + endif + enddo + + call ESMF_FieldGather(dzdt_input_grid, data3d_one_tile, rootPet=0, rc=rc) + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_dzdt(1)) > EPSILON) stop 20 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_dzdt(2)) > EPSILON) stop 21 + + call ESMF_FieldGather(pres_input_grid, data3d_one_tile, rootPet=0, rc=rc) + if (abs(data3d_one_tile(i_check(1),j_check(1),k_check(1)) - expected_values_pres(1)) > EPSILON) stop 22 + if (abs(data3d_one_tile(i_check(2),j_check(2),k_check(2)) - expected_values_pres(2)) > EPSILON) stop 23 + + call ESMF_FieldGather(wind_input_grid, data4d_one_tile, rootPet=0, rc=rc) + if (abs(data4d_one_tile(i_check(1),j_check(1),k_check(1),1) - expected_values_xwind(1)) > EPSILON) stop 24 + if (abs(data4d_one_tile(i_check(2),j_check(2),k_check(2),1) - expected_values_xwind(2)) > EPSILON) stop 25 + if (abs(data4d_one_tile(i_check(1),j_check(1),k_check(1),2) - expected_values_ywind(1)) > EPSILON) stop 26 + if (abs(data4d_one_tile(i_check(2),j_check(2),k_check(2),2) - expected_values_ywind(2)) > EPSILON) stop 27 + if (abs(data4d_one_tile(i_check(1),j_check(1),k_check(1),3) - expected_values_zwind(1)) > EPSILON) stop 28 + if (abs(data4d_one_tile(i_check(2),j_check(2),k_check(2),3) - expected_values_zwind(2)) > EPSILON) stop 29 + + call ESMF_FieldGather(ps_input_grid, data_one_tile, rootPet=0, rc=rc) + if (abs(data_one_tile(i_check(1),j_check(1)) - expected_values_ps(1)) > EPSILON) stop 32 + + call ESMF_FieldGather(terrain_input_grid, data_one_tile, rootPet=0, rc=rc) + if (abs(data_one_tile(i_check(1),j_check(1)) - expected_values_terrain(1)) > EPSILON) stop 34 + + deallocate(latitude, longitude, data3d_one_tile, data4d_one_tile, data_one_tile) + + call ESMF_finalize(endflag=ESMF_END_KEEPMPI) + + call mpi_finalize(rc) + + print*,"SUCCESS!" + + end program read_atm_grib2 diff --git a/tests/chgres_cube/ftst_read_sfc_grib2.F90 b/tests/chgres_cube/ftst_read_sfc_grib2.F90 new file mode 100644 index 000000000..5f587912a --- /dev/null +++ b/tests/chgres_cube/ftst_read_sfc_grib2.F90 @@ -0,0 +1,352 @@ + program read_sfc_grib2 + +! Unit test for the read_input_sfc_grib2_file routine. +! +! Reads a GFS GRIB2 file and compares the output +! to expected values. +! +! Author George Gayno + + use esmf + + use input_data, only : read_input_sfc_data, & + lsoil_input, & + terrain_input_grid, & + soilm_liq_input_grid, & + soilm_tot_input_grid, & + soil_temp_input_grid, & + landsea_mask_input_grid, & + seaice_fract_input_grid, & + seaice_depth_input_grid, & + seaice_skin_temp_input_grid, & + snow_liq_equiv_input_grid, & + snow_depth_input_grid, & + veg_type_input_grid, & + soil_type_input_grid, & + t2m_input_grid, & + q2m_input_grid, & + tprcp_input_grid, & + f10m_input_grid, & + ffmm_input_grid, & + ustar_input_grid, & + srflag_input_grid, & + skin_temp_input_grid, & + canopy_mc_input_grid, & + z0_input_grid + + use program_setup, only : external_model, data_dir_input_grid, & + grib2_file_input_grid, varmap_file, & + read_varmap, input_type + + use model_grid, only : input_grid, & + i_input, j_input, & + latitude_input_grid, & + longitude_input_grid + + implicit none + + integer, parameter :: NUM_VALUES=2 + + real, parameter :: EPSILON=0.001 + + integer :: localpet, npets, rc + + real(esmf_kind_r8), allocatable :: latitude(:,:) + real(esmf_kind_r8), allocatable :: longitude(:,:) + + real(esmf_kind_r8), allocatable :: data_one_tile(:,:) + real(esmf_kind_r8), allocatable :: data_one_tile_3d(:,:,:) + + type(esmf_vm) :: vm + + type(esmf_polekind_flag) :: polekindflag(2) + +! The expected values were determined by checking +! the input GRIB2 file using wgrib2. + + real :: landsea_mask_expected_values(NUM_VALUES) ! land-sea mask + real :: terrain_expected_values(NUM_VALUES) ! terrain height + real :: soilm_liq1_expected_values(NUM_VALUES) ! layer 1 liquid soil moisture + real :: soilm_liq2_expected_values(NUM_VALUES) ! layer 2 liquid soil moisture + real :: soilm_liq3_expected_values(NUM_VALUES) ! layer 3 liquid soil moisture + real :: soilm_liq4_expected_values(NUM_VALUES) ! layer 4 liquid soil moisture + real :: soilm_tot1_expected_values(NUM_VALUES) ! layer 1 total soil moisture + real :: soilm_tot2_expected_values(NUM_VALUES) ! layer 2 total soil moisture + real :: soilm_tot3_expected_values(NUM_VALUES) ! layer 3 total soil moisture + real :: soilm_tot4_expected_values(NUM_VALUES) ! layer 4 total soil moisture + real :: soil_temp1_expected_values(NUM_VALUES) ! layer 1 soil temperature + real :: soil_temp2_expected_values(NUM_VALUES) ! layer 2 soil temperature + real :: soil_temp3_expected_values(NUM_VALUES) ! layer 3 soil temperature + real :: soil_temp4_expected_values(NUM_VALUES) ! layer 4 soil temperature + real :: seaice_fract_expected_values(NUM_VALUES) ! sea ice fraction + real :: seaice_depth_expected_values(NUM_VALUES) ! sea ice depth + real :: seaice_skin_temp_expected_values(NUM_VALUES) ! sea ice skin temperature + real :: snow_liq_equiv_expected_values(NUM_VALUES) ! liquid equivalent snow depth + real :: snow_depth_expected_values(NUM_VALUES) ! physical snow depth + real :: veg_type_expected_values(NUM_VALUES) ! vegetation type + real :: soil_type_expected_values(NUM_VALUES) ! soil type + real :: t2m_expected_values(NUM_VALUES) ! two-meter temperature + real :: q2m_expected_values(NUM_VALUES) ! two-meter specific humidity + real :: tprcp_expected_values(NUM_VALUES) ! precipitation + real :: f10m_expected_values(NUM_VALUES) ! log((z0+10)*l/z0) + real :: ffmm_expected_values(NUM_VALUES) ! log((z0+z1)*l/z0) + real :: ustar_expected_values(NUM_VALUES) ! friction velocity + real :: srflag_expected_values(NUM_VALUES) ! snow/rain flag + real :: skin_temp_expected_values(NUM_VALUES) ! skin temperature + real :: canopy_mc_expected_values(NUM_VALUES) ! canopy moisture content + real :: z0_expected_values(NUM_VALUES) ! roughness length + + data terrain_expected_values / 2775.4197, 5.97e-02 / + data soilm_liq1_expected_values / 0.00, 0.00 / + data soilm_liq2_expected_values / 0.00, 0.00 / + data soilm_liq3_expected_values / 0.00, 0.00 / + data soilm_liq4_expected_values / 0.00, 0.00 / + data soilm_tot1_expected_values / 1.00, 0.00 / + data soilm_tot2_expected_values / 1.00, 0.00 / + data soilm_tot3_expected_values / 1.00, 0.00 / + data soilm_tot4_expected_values / 1.00, 0.00 / + data soil_temp1_expected_values / 236.1336, 265.0 / + data soil_temp2_expected_values / 228.5099, 265.0 / + data soil_temp3_expected_values / 225.7600, 265.0 / + data soil_temp4_expected_values / 228.1500, 265.0 / + data landsea_mask_expected_values / 1.0, 2.0 / + data seaice_fract_expected_values / 0.0, 1.0 / + data seaice_depth_expected_values / 1.5, 1.5/ + data seaice_skin_temp_expected_values / 235.8585, 243.8585/ + data snow_liq_equiv_expected_values / 120.0, 37.0 / + data snow_depth_expected_values / 1200.0, 110.0/ + data veg_type_expected_values / 15.0, 0.0 / + data soil_type_expected_values / -99999.0, -99999.0 / + data t2m_expected_values / 238.1991, 247.2991 / + data q2m_expected_values / 0.00016, 0.00035 / + data tprcp_expected_values / 0.0, 0.0 / + data f10m_expected_values / 0.0, 0.0/ + data ffmm_expected_values / 0.0, 0.0 / + data ustar_expected_values / 0.0, 0.0 / + data srflag_expected_values / 0.0, 0.0/ + data skin_temp_expected_values / 235.8585, 243.8585 / + data canopy_mc_expected_values / 0.0, 0.0 / + data z0_expected_values / 0.01, 0.01 / + + print*,"Starting test of read_atm_grib2_file." + + call mpi_init(rc) + + call ESMF_Initialize(rc=rc) + + call ESMF_VMGetGlobal(vm, rc=rc) + + call ESMF_VMGet(vm, localPet=localpet, petCount=npets, rc=rc) + + external_model="GFS" + input_type="grib2" +!data_dir_input_grid = "/scratch1/NCEPDEV/da/George.Gayno/noscrub/reg_tests/chgres_cube/input_data/gfs.grib2" + data_dir_input_grid = "data" + grib2_file_input_grid = "gfs.t00z.pgrb2.0p50.f000" + + i_input = 720 + j_input = 361 + + polekindflag(1:2) = ESMF_POLEKIND_MONOPOLE + input_grid = ESMF_GridCreate1PeriDim(minIndex=(/1,1/), & + maxIndex=(/i_input,j_input/), & + polekindflag=polekindflag, & + periodicDim=1, & + poleDim=2, & + coordSys=ESMF_COORDSYS_SPH_DEG, & + regDecomp=(/1,npets/), & + indexflag=ESMF_INDEX_GLOBAL, rc=rc) + + + varmap_file ="./data/GFSphys_varmap.txt" + call read_varmap + + 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) + +! Lat/lon used in surface read. Use flag values. + + allocate(latitude(i_input,j_input)) + allocate(longitude(i_input,j_input)) + latitude=90.0 + longitude=0.0 + + call ESMF_FieldScatter(longitude_input_grid, longitude, rootpet=0, rc=rc) + call ESMF_FieldScatter(latitude_input_grid, latitude, rootpet=0, rc=rc) + +! Call the chgres_cube read routine. + + call read_input_sfc_data(localpet) + + allocate(data_one_tile(i_input,j_input)) + allocate(data_one_tile_3d(i_input,j_input,lsoil_input)) + + call ESMF_FieldGather(terrain_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - terrain_expected_values(1)) > EPSILON) stop 6 + if (abs(data_one_tile(i_input,1) - terrain_expected_values(2)) > EPSILON) stop 8 + endif + + call ESMF_FieldGather(soilm_liq_input_grid, data_one_tile_3d, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile_3d(1,j_input,1) - soilm_liq1_expected_values(1)) > EPSILON) stop 10 + if (abs(data_one_tile_3d(i_input,1,1) - soilm_liq1_expected_values(2)) > EPSILON) stop 11 + if (abs(data_one_tile_3d(1,j_input,2) - soilm_liq2_expected_values(1)) > EPSILON) stop 12 + if (abs(data_one_tile_3d(i_input,1,2) - soilm_liq2_expected_values(2)) > EPSILON) stop 13 + if (abs(data_one_tile_3d(1,j_input,3) - soilm_liq3_expected_values(1)) > EPSILON) stop 14 + if (abs(data_one_tile_3d(i_input,1,3) - soilm_liq3_expected_values(2)) > EPSILON) stop 15 + if (abs(data_one_tile_3d(1,j_input,4) - soilm_liq4_expected_values(1)) > EPSILON) stop 16 + if (abs(data_one_tile_3d(i_input,1,4) - soilm_liq4_expected_values(2)) > EPSILON) stop 17 + endif + + call ESMF_FieldGather(soilm_tot_input_grid, data_one_tile_3d, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile_3d(1,j_input,1) - soilm_tot1_expected_values(1)) > EPSILON) stop 20 + if (abs(data_one_tile_3d(i_input,1,1) - soilm_tot1_expected_values(2)) > EPSILON) stop 21 + if (abs(data_one_tile_3d(1,j_input,2) - soilm_tot2_expected_values(1)) > EPSILON) stop 22 + if (abs(data_one_tile_3d(i_input,1,2) - soilm_tot2_expected_values(2)) > EPSILON) stop 23 + if (abs(data_one_tile_3d(1,j_input,3) - soilm_tot3_expected_values(1)) > EPSILON) stop 24 + if (abs(data_one_tile_3d(i_input,1,3) - soilm_tot3_expected_values(2)) > EPSILON) stop 25 + if (abs(data_one_tile_3d(1,j_input,4) - soilm_tot4_expected_values(1)) > EPSILON) stop 26 + if (abs(data_one_tile_3d(i_input,1,4) - soilm_tot4_expected_values(2)) > EPSILON) stop 27 + endif + + call ESMF_FieldGather(soil_temp_input_grid, data_one_tile_3d, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile_3d(1,j_input,1) - soil_temp1_expected_values(1)) > EPSILON) stop 30 + if (abs(data_one_tile_3d(i_input,1,1) - soil_temp1_expected_values(2)) > EPSILON) stop 31 + if (abs(data_one_tile_3d(1,j_input,2) - soil_temp2_expected_values(1)) > EPSILON) stop 32 + if (abs(data_one_tile_3d(i_input,1,2) - soil_temp2_expected_values(2)) > EPSILON) stop 33 + if (abs(data_one_tile_3d(1,j_input,3) - soil_temp3_expected_values(1)) > EPSILON) stop 34 + if (abs(data_one_tile_3d(i_input,1,3) - soil_temp3_expected_values(2)) > EPSILON) stop 35 + if (abs(data_one_tile_3d(1,j_input,4) - soil_temp4_expected_values(1)) > EPSILON) stop 36 + if (abs(data_one_tile_3d(i_input,1,4) - soil_temp4_expected_values(2)) > EPSILON) stop 37 + endif + + call ESMF_FieldGather(landsea_mask_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - landsea_mask_expected_values(1)) > EPSILON) stop 39 + if (abs(data_one_tile(i_input,1) - landsea_mask_expected_values(2)) > EPSILON) stop 40 + endif + + call ESMF_FieldGather(seaice_fract_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - seaice_fract_expected_values(1)) > EPSILON) stop 41 + if (abs(data_one_tile(i_input,1) - seaice_fract_expected_values(2)) > EPSILON) stop 42 + endif + + call ESMF_FieldGather(seaice_depth_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - seaice_depth_expected_values(1)) > EPSILON) stop 43 + if (abs(data_one_tile(i_input,1) - seaice_depth_expected_values(2)) > EPSILON) stop 44 + endif + + call ESMF_FieldGather(seaice_skin_temp_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - seaice_skin_temp_expected_values(1)) > EPSILON) stop 45 + if (abs(data_one_tile(i_input,1) - seaice_skin_temp_expected_values(2)) > EPSILON) stop 46 + endif + + call ESMF_FieldGather(snow_liq_equiv_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - snow_liq_equiv_expected_values(1)) > EPSILON) stop 47 + if (abs(data_one_tile(i_input,1) - snow_liq_equiv_expected_values(2)) > EPSILON) stop 48 + endif + + call ESMF_FieldGather(snow_depth_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - snow_depth_expected_values(1)) > EPSILON) stop 49 + if (abs(data_one_tile(i_input,1) - snow_depth_expected_values(2)) > EPSILON) stop 50 + endif + + call ESMF_FieldGather(veg_type_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - veg_type_expected_values(1)) > EPSILON) stop 51 + if (abs(data_one_tile(i_input,1) - veg_type_expected_values(2)) > EPSILON) stop 52 + endif + + call ESMF_FieldGather(soil_type_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - soil_type_expected_values(1)) > EPSILON) stop 53 + if (abs(data_one_tile(i_input,1) - soil_type_expected_values(2)) > EPSILON) stop 54 + endif + + call ESMF_FieldGather(t2m_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - t2m_expected_values(1)) > EPSILON) stop 55 + if (abs(data_one_tile(i_input,1) - t2m_expected_values(2)) > EPSILON) stop 56 + endif + + call ESMF_FieldGather(q2m_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - q2m_expected_values(1)) > EPSILON) stop 57 + if (abs(data_one_tile(i_input,1) - q2m_expected_values(2)) > EPSILON) stop 58 + endif + + call ESMF_FieldGather(tprcp_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - tprcp_expected_values(1)) > EPSILON) stop 59 + if (abs(data_one_tile(i_input,1) - tprcp_expected_values(2)) > EPSILON) stop 60 + endif + + call ESMF_FieldGather(f10m_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - f10m_expected_values(1)) > EPSILON) stop 61 + if (abs(data_one_tile(i_input,1) - f10m_expected_values(2)) > EPSILON) stop 62 + endif + + call ESMF_FieldGather(ffmm_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - ffmm_expected_values(1)) > EPSILON) stop 63 + if (abs(data_one_tile(i_input,1) - ffmm_expected_values(2)) > EPSILON) stop 64 + endif + + call ESMF_FieldGather(ustar_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - ustar_expected_values(1)) > EPSILON) stop 65 + if (abs(data_one_tile(i_input,1) - ustar_expected_values(2)) > EPSILON) stop 66 + endif + + call ESMF_FieldGather(srflag_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - srflag_expected_values(1)) > EPSILON) stop 67 + if (abs(data_one_tile(i_input,1) - srflag_expected_values(2)) > EPSILON) stop 68 + endif + + call ESMF_FieldGather(skin_temp_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - skin_temp_expected_values(1)) > EPSILON) stop 69 + if (abs(data_one_tile(i_input,1) - skin_temp_expected_values(2)) > EPSILON) stop 70 + endif + + call ESMF_FieldGather(canopy_mc_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - canopy_mc_expected_values(1)) > EPSILON) stop 71 + if (abs(data_one_tile(i_input,1) - canopy_mc_expected_values(2)) > EPSILON) stop 72 + endif + + call ESMF_FieldGather(z0_input_grid, data_one_tile, rootPet=0, rc=rc) + if (localpet == 0) then + if (abs(data_one_tile(1,j_input) - z0_expected_values(1)) > EPSILON) stop 73 + if (abs(data_one_tile(i_input,1) - z0_expected_values(2)) > EPSILON) stop 74 + endif + + deallocate (latitude, longitude) + deallocate (data_one_tile, data_one_tile_3d) + + call ESMF_finalize(endflag=ESMF_END_KEEPMPI) + + call mpi_finalize(rc) + + print*,"SUCCESS!" + + end program read_sfc_grib2 diff --git a/tests/chgres_cube/ftst_sfc_input_data.F90 b/tests/chgres_cube/ftst_sfc_input_data.F90 index e69db1763..75bf1bf19 100644 --- a/tests/chgres_cube/ftst_sfc_input_data.F90 +++ b/tests/chgres_cube/ftst_sfc_input_data.F90 @@ -22,7 +22,7 @@ program test_sfc_input_data soilt_updated(:,:,:), & soilt_correct(:,:,:) real(esmf_kind_r8), allocatable :: skint(:,:) - real(esmf_kind_r4), allocatable :: cnwat_bad(:,:), & + real(esmf_kind_r8), allocatable :: cnwat_bad(:,:), & cnwat_updated(:,:), & cnwat_correct(:,:) diff --git a/ush/chgres_cube.sh b/ush/chgres_cube.sh index c60eba605..550439049 100755 --- a/ush/chgres_cube.sh +++ b/ush/chgres_cube.sh @@ -272,8 +272,8 @@ cat << EOF > ./fort.41 convert_sfc=$CONVERT_SFC convert_nst=$CONVERT_NST input_type="${INPUT_TYPE}" - tracers=$TRACERS_TARGET - tracers_input=$TRACERS_INPUT + tracers=${TRACERS_TARGET} + tracers_input=${TRACERS_INPUT} regional=$REGIONAL halo_bndy=$HALO_BNDY halo_blend=$HALO_BLEND