From dc0e4a61419b95805a22e05d477cb58a33e581f8 Mon Sep 17 00:00:00 2001
From: ShanSun-NOAA <125340914+ShanSun-NOAA@users.noreply.github.com>
Date: Mon, 6 Nov 2023 12:55:16 -0700
Subject: [PATCH 1/3] Update grid generation process to prevent coastal lakes
(#856)
Logic is added to programs 'inland' and 'lake' to remove coastal lakes.
Also, an option is added to choose the observational datasets to generate lake mask and
lake depth. These options include:
- Lake fraction: GLDBv3, MODIS+ and VIIRS
- Lake depth: GLDBv3 and GloBathy
Fixes #854.
---
docs/source/ufs_utils.rst | 9 +-
driver_scripts/driver_grid.hera.sh | 9 +-
driver_scripts/driver_grid.jet.sh | 9 +-
driver_scripts/driver_grid.orion.sh | 9 +-
driver_scripts/driver_grid.wcoss2.sh | 9 +-
reg_tests/grid_gen/c96.uniform.sh | 10 +-
reg_tests/grid_gen/driver.hera.sh | 2 +-
reg_tests/grid_gen/driver.jet.sh | 2 +-
reg_tests/grid_gen/driver.wcoss2.sh | 2 +-
sorc/orog_mask_tools.fd/inland.fd/inland.F90 | 38 +-
sorc/orog_mask_tools.fd/lake.fd/lakefrac.F90 | 540 ++++++++++++-------
ush/fv3gfs_driver_grid.sh | 6 +-
ush/fv3gfs_make_lake.sh | 32 +-
13 files changed, 460 insertions(+), 217 deletions(-)
diff --git a/docs/source/ufs_utils.rst b/docs/source/ufs_utils.rst
index 314c179b9..7810f3817 100644
--- a/docs/source/ufs_utils.rst
+++ b/docs/source/ufs_utils.rst
@@ -375,8 +375,13 @@ Program inputs and outputs
* grid file - the "grid" file from the make_hgrid or regional_esg programs - CRES_grid.tile#.nc - (NetCDF)
* orography file - the orography file including the 'inland' flag record from the inland program - oro.CRES.tile#.nc (NetCDF)
- * lake status code file - GlobalLakeStatus.dat (located in `./fix/fix_orog `_). See GlobalLakeStatus.txt for the defintion of each code.
- * lake depth file - GlobalLakeDepth.dat (located in `./fix/fix_orog `_). See GlobalLakeDepth.txt for a description of this file.
+ * lake status code file - One of the following files. (located in `./fix/fix_orog `_). See GlobalLakeStatus.txt for a description of the file format.
+ * GlobalLakeStatus_MOSISp.dat
+ * GlobalLakeStatus_GLDBv3release.dat
+ * GlobalLakeStatus_VIIRS.dat
+ * lake depth file - One of the following files. (located in `./fix/fix_orog `_). See GlobalLakeDepth.txt for a description of this file.
+ * GlobalLakeDepth_GLDBv3release.dat
+ * GlobalLakeDepth_GLOBathy.dat
**Output data:**
diff --git a/driver_scripts/driver_grid.hera.sh b/driver_scripts/driver_grid.hera.sh
index 63d1b872e..6975857a3 100755
--- a/driver_scripts/driver_grid.hera.sh
+++ b/driver_scripts/driver_grid.hera.sh
@@ -106,10 +106,15 @@ export soil_type_src="bnu.v3.30s" # Soil type data.
# For Beijing Norm. Univ. data
# 1) "bnu.v3.30s" for global 30s data.
+# choose dataset sources for lakefrac & lakedepth so that lake_data_srce=LakeFrac_LakeDepth;
+# available options are 'MODISP_GLDBV3', 'MODISP_GLOBATHY', 'VIIRS_GLDBV3', 'VIIRS_GLOBATHY' & 'GLDBV3'
+export lake_data_srce=MODISP_GLDBV3
+
if [ $gtype = uniform ]; then
export res=96
- export add_lake=false # Add lake frac and depth to orography data.
- export lake_cutoff=0.20 # lake frac < lake_cutoff ignored when add_lake=T
+ export add_lake=true # Add lake frac and depth to orography data.
+ export lake_cutoff=0.50 # return 0 if lake_frac < lake_cutoff & add_lake=T
+ export binary_lake=1 # return 1 if lake_frac >= lake_cutoff & add_lake=T
elif [ $gtype = stretch ]; then
export res=96
export stretch_fac=1.5 # Stretching factor for the grid
diff --git a/driver_scripts/driver_grid.jet.sh b/driver_scripts/driver_grid.jet.sh
index fe2d28dc5..8cfce4d89 100755
--- a/driver_scripts/driver_grid.jet.sh
+++ b/driver_scripts/driver_grid.jet.sh
@@ -104,10 +104,15 @@ export soil_type_src="bnu.v3.30s" # Soil type data.
# 4) "statsgo.nh.30s" for NH 30s data
# 5) "statsgo.30s" for global 30s data
+# choose dataset sources for lakefrac & lakedepth so that lake_data_srce=LakeFrac_LakeDepth;
+# available options are 'MODISP_GLDBV3', 'MODISP_GLOBATHY', 'VIIRS_GLDBV3', 'VIIRS_GLOBATHY' & 'GLDBV3'
+export lake_data_srce=MODISP_GLDBV3
+
if [ $gtype = uniform ]; then
export res=96
- export add_lake=false # Add lake frac and depth to orography data.
- export lake_cutoff=0.20 # lake frac < lake_cutoff ignored when add_lake=T
+ export add_lake=true # Add lake frac and depth to orography data.
+ export lake_cutoff=0.50 # return 0 if lake_frac < lake_cutoff & add_lake=T
+ export binary_lake=1 # return 1 if lake_frac >= lake_cutoff & add_lake=T
elif [ $gtype = stretch ]; then
export res=96
export stretch_fac=1.5 # Stretching factor for the grid
diff --git a/driver_scripts/driver_grid.orion.sh b/driver_scripts/driver_grid.orion.sh
index c0190f4d9..458abc318 100755
--- a/driver_scripts/driver_grid.orion.sh
+++ b/driver_scripts/driver_grid.orion.sh
@@ -103,10 +103,15 @@ export soil_type_src="bnu.v3.30s" # Soil type data.
# 4) "statsgo.nh.30s" for NH 30s data
# 5) "statsgo.30s" for global 30s data
+# choose dataset sources for lakefrac & lakedepth so that lake_data_srce=LakeFrac_LakeDepth;
+# available options are 'MODISP_GLDBV3', 'MODISP_GLOBATHY', 'VIIRS_GLDBV3', 'VIIRS_GLOBATHY' & 'GLDBV3'
+export lake_data_srce=MODISP_GLDBV3
+
if [ $gtype = uniform ]; then
export res=96
- export add_lake=false # Add lake frac and depth to orography data.
- export lake_cutoff=0.20 # lake frac < lake_cutoff ignored when add_lake=T
+ export add_lake=true # Add lake frac and depth to orography data.
+ export lake_cutoff=0.50 # return 0 if lake_frac < lake_cutoff & add_lake=T
+ export binary_lake=1 # return 1 if lake_frac >= lake_cutoff & add_lake=T
elif [ $gtype = stretch ]; then
export res=96
export stretch_fac=1.5 # Stretching factor for the grid
diff --git a/driver_scripts/driver_grid.wcoss2.sh b/driver_scripts/driver_grid.wcoss2.sh
index cbb5ef188..c5bb48919 100755
--- a/driver_scripts/driver_grid.wcoss2.sh
+++ b/driver_scripts/driver_grid.wcoss2.sh
@@ -102,10 +102,15 @@ export soil_type_src="bnu.v3.30s" # Soil type data
# 4) "statsgo.nh.30s" for NH 30s data
# 5) "statsgo.30s" for global 30s data
+# choose dataset sources for lakefrac & lakedepth so that lake_data_srce=LakeFrac_LakeDepth;
+# available options are 'MODISP_GLDBV3', 'MODISP_GLOBATHY', 'VIIRS_GLDBV3', 'VIIRS_GLOBATHY' & 'GLDBV3'
+export lake_data_srce=MODISP_GLDBV3
+
if [ $gtype = uniform ]; then
export res=96
- export add_lake=false # Add lake frac and depth to orography data.
- export lake_cutoff=0.20 # lake frac < lake_cutoff ignored when add_lake=T
+ export add_lake=true # Add lake frac and depth to orography data.
+ export lake_cutoff=0.50 # return 0 if lake_frac < lake_cutoff & add_lake=T
+ export binary_lake=1 # return 1 if lake_frac >= lake_cutoff & add_lake=T
elif [ $gtype = stretch ]; then
export res=96
export stretch_fac=1.5 # Stretching factor for the grid
diff --git a/reg_tests/grid_gen/c96.uniform.sh b/reg_tests/grid_gen/c96.uniform.sh
index 6811c71af..09e18c843 100755
--- a/reg_tests/grid_gen/c96.uniform.sh
+++ b/reg_tests/grid_gen/c96.uniform.sh
@@ -1,9 +1,9 @@
#!/bin/bash
#-----------------------------------------------------------------------
-# Create a C96 global uniform grid. Compare output to a set
-# of baseline files using the 'nccmp' utility. This script is
-# run by the machine specific driver script.
+# Create a C96 global uniform grid including inland lakes. Compare
+# output to a set of baseline files using the 'nccmp' utility. This
+# script is run by the machine specific driver script.
#-----------------------------------------------------------------------
set -x
@@ -13,6 +13,10 @@ export out_dir=${WORK_DIR}/c96.uniform
export res=96
export gtype=uniform
+export add_lake=true
+export lake_data_srce=MODISP_GLDBV3
+export lake_cutoff=0.50
+export binary_lake=1
NCCMP=${NCCMP:-$(which nccmp)}
diff --git a/reg_tests/grid_gen/driver.hera.sh b/reg_tests/grid_gen/driver.hera.sh
index c0211cc73..66673ab34 100755
--- a/reg_tests/grid_gen/driver.hera.sh
+++ b/reg_tests/grid_gen/driver.hera.sh
@@ -66,7 +66,7 @@ export OMP_NUM_THREADS=24
#-----------------------------------------------------------------------------
LOG_FILE1=${LOG_FILE}01
-TEST1=$(sbatch --parsable --ntasks-per-node=24 --nodes=1 -t 0:10:00 -A $PROJECT_CODE -q $QUEUE -J c96.uniform \
+TEST1=$(sbatch --parsable --ntasks-per-node=24 --nodes=1 -t 0:15:00 -A $PROJECT_CODE -q $QUEUE -J c96.uniform \
-o $LOG_FILE1 -e $LOG_FILE1 ./c96.uniform.sh)
#-----------------------------------------------------------------------------
diff --git a/reg_tests/grid_gen/driver.jet.sh b/reg_tests/grid_gen/driver.jet.sh
index 6641098bc..db387c9d4 100755
--- a/reg_tests/grid_gen/driver.jet.sh
+++ b/reg_tests/grid_gen/driver.jet.sh
@@ -64,7 +64,7 @@ export OMP_NUM_THREADS=24
#-----------------------------------------------------------------------------
LOG_FILE1=${LOG_FILE}01
-TEST1=$(sbatch --parsable --ntasks-per-node=24 --nodes=1 -t 0:10:00 -A $PROJECT_CODE -q $QUEUE -J c96.uniform \
+TEST1=$(sbatch --parsable --ntasks-per-node=24 --nodes=1 -t 0:20:00 -A $PROJECT_CODE -q $QUEUE -J c96.uniform \
--partition=xjet -o $LOG_FILE1 -e $LOG_FILE1 ./c96.uniform.sh)
#-----------------------------------------------------------------------------
diff --git a/reg_tests/grid_gen/driver.wcoss2.sh b/reg_tests/grid_gen/driver.wcoss2.sh
index 398765e1c..35c077f34 100755
--- a/reg_tests/grid_gen/driver.wcoss2.sh
+++ b/reg_tests/grid_gen/driver.wcoss2.sh
@@ -67,7 +67,7 @@ rm -fr $WORK_DIR
#-----------------------------------------------------------------------------
LOG_FILE1=${LOG_FILE}01
-TEST1=$(qsub -V -o $LOG_FILE1 -e $LOG_FILE1 -q $QUEUE -A $PROJECT_CODE -l walltime=00:10:00 \
+TEST1=$(qsub -V -o $LOG_FILE1 -e $LOG_FILE1 -q $QUEUE -A $PROJECT_CODE -l walltime=00:15:00 \
-N c96.uniform -l select=1:ncpus=30:mem=40GB $PWD/c96.uniform.sh)
#-----------------------------------------------------------------------------
diff --git a/sorc/orog_mask_tools.fd/inland.fd/inland.F90 b/sorc/orog_mask_tools.fd/inland.fd/inland.F90
index 057c648d3..66398e2b2 100644
--- a/sorc/orog_mask_tools.fd/inland.fd/inland.F90
+++ b/sorc/orog_mask_tools.fd/inland.fd/inland.F90
@@ -15,7 +15,7 @@ PROGRAM inland_mask
REAL, ALLOCATABLE :: inland(:,:,:)
REAL, ALLOCATABLE :: land_frac(:,:,:)
- INTEGER :: i_ctr, j_ctr, tile_beg, tile_end
+ INTEGER :: tile_beg, tile_end
INTEGER :: cs_res, x_res, y_res
CHARACTER(len=32) :: arg
INTEGER :: stat
@@ -23,7 +23,7 @@ PROGRAM inland_mask
REAL :: cutoff
CHARACTER(len=1) :: reg
- LOGICAL, ALLOCATABLE :: done(:,:,:)
+ LOGICAL, ALLOCATABLE :: done(:,:,:)
CALL getarg(0, arg) ! get the program name
IF (iargc() /= 3 .AND. iargc() /= 4) THEN
@@ -78,14 +78,19 @@ PROGRAM inland_mask
!! @author Ning Wang
SUBROUTINE mark_global_inland(cs_res)
INTEGER, INTENT(IN) :: cs_res
+ INTEGER :: i_seed, j_seed
ALLOCATE(done(cs_res,cs_res,6))
ALLOCATE(inland(cs_res,cs_res,6))
done = .false.
inland = 1.0
- i_ctr = cs_res/2; j_ctr = cs_res/2
- CALL mark_global_inland_rec_d(i_ctr, j_ctr, 2, 0)
+ i_seed = cs_res/2; j_seed = cs_res/2
+ CALL mark_global_inland_rec_d(i_seed, j_seed, 2, 0)
+
+! to make sure black sea is excluded
+ i_seed = REAL(cs_res)/32.0*3; j_seed = i_seed
+ CALL mark_global_inland_rec_d(i_seed, j_seed, 3, 0)
DEALLOCATE(done)
@@ -99,6 +104,7 @@ END SUBROUTINE mark_global_inland
SUBROUTINE mark_inland_reg(cs_res)
INTEGER, INTENT(IN) :: cs_res
INTEGER :: i_seed, j_seed
+ INTEGER :: i
ALLOCATE(done(x_res,y_res,1))
ALLOCATE(inland(x_res,y_res,1))
@@ -116,6 +122,30 @@ SUBROUTINE mark_inland_reg(cs_res)
i_seed = x_res/3; j_seed = 1
CALL mark_regional_inland_rec_d(i_seed, j_seed, 1, 0)
+ j_seed = 1
+ DO i = 1, x_res
+ CALL mark_regional_inland_rec_d(i, j_seed, 1, 0)
+ ENDDO
+
+ j_seed = y_res
+ DO i = x_res/2, x_res
+ CALL mark_regional_inland_rec_d(i, j_seed, 1, 0)
+ ENDDO
+
+! set up additional 3 seeds for ESG CONUS grid
+! i_seed = 1600; j_seed = 1040
+! i_seed = x_res - 10; j_seed = y_res
+! CALL mark_regional_inland_rec_d(i_seed, j_seed, 1, 0)
+
+! i_seed = x_res - 60; j_seed = y_res
+! CALL mark_regional_inland_rec_d(i_seed, j_seed, 1, 0)
+
+! i_seed = x_res - 275; j_seed = y_res
+! CALL mark_regional_inland_rec_d(i_seed, j_seed, 1, 0)
+
+! i_seed = 500; j_seed = 1
+! CALL mark_regional_inland_rec_d(i_seed, j_seed, 1, 0)
+
DEALLOCATE(done)
END SUBROUTINE mark_inland_reg
diff --git a/sorc/orog_mask_tools.fd/lake.fd/lakefrac.F90 b/sorc/orog_mask_tools.fd/lake.fd/lakefrac.F90
index 47f2fff60..ad0f6e184 100644
--- a/sorc/orog_mask_tools.fd/lake.fd/lakefrac.F90
+++ b/sorc/orog_mask_tools.fd/lake.fd/lakefrac.F90
@@ -15,7 +15,7 @@
!! - Ning Wang, Apr. 2019: Extended the program to process the same lake data
!! for FV3 stand-alone regional (SAR) model.
!!
-!! @return 0 for successful completion and for error.
+!! @return 0 for success.
!#define DIAG_N_VERBOSE
#define ADD_ATT_FOR_NEW_VAR
PROGRAM lake_frac
@@ -32,41 +32,53 @@ PROGRAM lake_frac
REAL, ALLOCATABLE :: cs_lakestatus(:), cs_lakedepth(:)
REAL, ALLOCATABLE :: src_grid_lon(:), src_grid_lat(:)
- INTEGER :: tile_req, tile_beg, tile_end
+ INTEGER :: tile_req, tile_beg, tile_end, binary_lake
REAL :: lake_cutoff
INTEGER, PARAMETER :: nlat = 21600, nlon = 43200
REAL, PARAMETER :: d2r = acos(-1.0) / 180.0
REAL, PARAMETER :: r2d = 180.0 /acos(-1.0)
REAL, PARAMETER :: pi = acos(-1.0)
- REAL*8, PARAMETER :: gppdeg = 119.99444445
- REAL*8, PARAMETER :: delta = 1.0 / 119.99444445
+ REAL*8, PARAMETER :: gppdeg = 120.0
+ REAL*8, PARAMETER :: delta = 1.0 / 120.0
- CHARACTER(len=32) :: arg
+ CHARACTER(len=32) :: arg, lakestatus_srce, lakedepth_srce
CHARACTER(len=256) :: lakedata_path
INTEGER :: stat
CALL getarg(0, arg) ! get the program name
- IF (iargc() /= 3 .AND. iargc() /= 4) THEN
+ IF (iargc() /= 5 .AND. iargc() /= 7) THEN
PRINT*, 'Usage: ', trim(arg), &
- ' [tile_num (0:all tiles, 7:regional)] [resolution (48,96, ...)] [path to lake data file]'
+ ' [tile_num (0:all tiles, 7:regional)] [resolution (48,96, ...)] &
+ [lake data path] [lake status source] [lake depth source]'
PRINT*, 'Or: ', trim(arg), &
- ' [tile_num (0:all tiles, 7:regional)] [resolution (48,96, ...)] [path to lake data file] [lake_cutoff]'
- STOP
+ ' [tile_num (0:all tiles, 7:regional)] [resolution (48,96, ...)] &
+ [lake data path] [lake status source] [lake depth source] [lake_cutoff] [binary_lake]'
+ STOP -1
ENDIF
CALL getarg(1, arg)
READ(arg,*,iostat=stat) tile_req
CALL getarg(2, arg)
READ(arg,*,iostat=stat) cs_res
CALL getarg(3, lakedata_path)
+ CALL getarg(4, lakestatus_srce)
+ CALL getarg(5, lakedepth_srce)
- IF (iargc() == 3) THEN
- lake_cutoff = 0.20
+ IF (iargc() == 5) THEN
+ lake_cutoff = 0.50
+ binary_lake = 1
ELSE
- CALL getarg(4, arg)
+ CALL getarg(6, arg)
READ(arg,*,iostat=stat) lake_cutoff
+ CALL getarg(7, arg)
+ READ(arg,*,iostat=stat) binary_lake
ENDIF
+ PRINT*, 'lake status source:', trim(lakestatus_srce)
+ PRINT*, 'lake depth source:', trim(lakedepth_srce)
+ PRINT*, 'lake cutoff:', lake_cutoff
+ PRINT*, 'binary lake:', binary_lake
+
IF (tile_req == 0) THEN
tile_beg = 1; tile_end = 6
PRINT*, 'Process tile 1 - 6 at resolution C',cs_res
@@ -91,17 +103,31 @@ PROGRAM lake_frac
ELSE
CALL read_cubed_sphere_reg_grid(cs_res, cs_grid, 3, res_x, res_y)
ENDIF
- ! compute source grid
+
+ ! allocate and compute source grid
ALLOCATE(src_grid_lon(nlon), src_grid_lat(nlat))
- DO i = 1, nlon
- src_grid_lon(i) = -180.0 + delta * (i-1)
- ENDDO
- DO i = 1, nlat
- src_grid_lat(i) = 90.0 - delta * (i-1)
- ENDDO
+
+ IF (lakestatus_srce == "GLDBV2" .OR. lakestatus_srce == "GLDBV3") THEN
+ ! GLDB data points are at the lower right corners of the grid cells
+ DO i = 1, nlon
+ src_grid_lon(i) = -180.0 + delta * i
+ ENDDO
+ DO i = 1, nlat
+ src_grid_lat(i) = 90.0 - delta * i
+ ENDDO
+ ENDIF
+
+ IF (lakestatus_srce == "MODISP" .OR. lakestatus_srce == "VIIRS") THEN
+ ! GLDB data points are at the upprt left corners of the grid cells
+ DO i = 1, nlon
+ src_grid_lon(i) = -180.0 + delta * (i-1)
+ ENDDO
+ DO i = 1, nlat
+ src_grid_lat(i) = 90.0 - delta * (i-1)
+ ENDDO
+ ENDIF
! read in lake data file
-! sfcdata_path = '/scratch1/NCEPDEV/global/glopara/fix/orog/'
lakedata_path = trim(lakedata_path) // "/"
ALLOCATE(lakestatus(nlon*nlat),lakedepth(nlon*nlat))
PRINT*, 'Read in lake data file ...'
@@ -115,7 +141,7 @@ PROGRAM lake_frac
PRINT*, 'Calculate lake fraction and average depth for cubed-sphere cells ...'
CALL cal_lake_frac_depth(lakestatus,cs_lakestatus,lakedepth,cs_lakedepth)
- ! write lake status (in terms of fraction) and lake depth(average)
+ ! write lake status (in terms of fraction) and lake depth(average, in meters)
! to a netcdf file
IF (tile_req /= 7) THEN
PRINT*, 'Write lake fraction/depth on cubed sphere grid cells to netCDF files ...'
@@ -130,7 +156,7 @@ PROGRAM lake_frac
DEALLOCATE(lakestatus,lakedepth)
DEALLOCATE(src_grid_lat, src_grid_lon)
- STOP
+ STOP 0
CONTAINS
!> Calculate lake fraction and depth on the model grid from
@@ -157,7 +183,9 @@ SUBROUTINE cal_lake_frac_depth(lakestat,cs_lakestat,lakedpth,cs_lakedpth)
INTEGER :: src_grid_lon_beg1,src_grid_lon_end1,src_grid_lon_beg2,src_grid_lon_end2
INTEGER :: grid_ct, lake_ct, co_gc, tmp
- REAL*8 :: lake_dpth_sum
+ INTEGER*1 :: lkst
+ INTEGER*2 :: lkdp
+ REAL*8 :: lake_dpth_sum, lake_avg_frac
LOGICAL :: two_section, enclosure_cnvx
IF (tile_req /= 7) THEN
@@ -234,13 +262,11 @@ SUBROUTINE cal_lake_frac_depth(lakestat,cs_lakestat,lakedpth,cs_lakedpth)
src_grid_lon_end = nint((180.0+lonmax)*gppdeg+0.5)
IF (src_grid_lat_beg > src_grid_lat_end) THEN
- print*,'switch!!!'
tmp = src_grid_lat_beg
src_grid_lat_beg = src_grid_lat_end
src_grid_lat_end = tmp
ENDIF
IF (src_grid_lon_beg > src_grid_lon_end) THEN
- print*,'switch!!!'
tmp = src_grid_lon_beg
src_grid_lon_beg = src_grid_lon_end
src_grid_lon_end = tmp
@@ -263,88 +289,65 @@ SUBROUTINE cal_lake_frac_depth(lakestat,cs_lakestat,lakedpth,cs_lakedpth)
#endif
lake_ct = 0; grid_ct = 0
lake_dpth_sum = 0.0
+ lake_avg_frac = 0.0
DO j = src_grid_lat_beg, src_grid_lat_end, stride_lat
stride_lon = int(1.0/cos(src_grid_lat(j)*d2r)*REAL(stride_lat))
#ifdef DIAG_N_VERBOSE
- IF (j == src_grid_lat_beg) THEN
- PRINT*, 'lon index range and stride', &
- src_grid_lon_beg,src_grid_lon_end,stride_lon
- PRINT*, 'lon range ', &
- src_grid_lon(src_grid_lon_beg),src_grid_lon(src_grid_lon_end)
- IF (two_section == .true.) THEN
- PRINT*, 'section1 index lon range and stride', &
- src_grid_lon_beg1,src_grid_lon_end1,stride_lon
- PRINT*, 'section1 lon range ', &
- src_grid_lon(src_grid_lon_beg1),src_grid_lon(src_grid_lon_end1)
- PRINT*, 'section2 index lon range and stride', &
- src_grid_lon_beg2,src_grid_lon_end2,stride_lon
- PRINT*, 'section2 lon range ', &
- src_grid_lon(src_grid_lon_beg2),src_grid_lon(src_grid_lon_end2)
+ IF (j == src_grid_lat_beg) THEN
+ PRINT*, 'lon index range and stride', &
+ src_grid_lon_beg,src_grid_lon_end,stride_lon
+ PRINT*, 'lon range ', &
+ src_grid_lon(src_grid_lon_beg),src_grid_lon(src_grid_lon_end)
+ IF (two_section .eqv. .true.) THEN
+ PRINT*, 'section1 index lon range and stride', &
+ src_grid_lon_beg1,src_grid_lon_end1,stride_lon
+ PRINT*, 'section1 lon range ', &
+ src_grid_lon(src_grid_lon_beg1),src_grid_lon(src_grid_lon_end1)
+ PRINT*, 'section2 index lon range and stride', &
+ src_grid_lon_beg2,src_grid_lon_end2,stride_lon
+ PRINT*, 'section2 lon range ', &
+ src_grid_lon(src_grid_lon_beg2),src_grid_lon(src_grid_lon_end2)
+ ENDIF
ENDIF
- ENDIF
#endif
- IF (two_section .EQV. .false.) THEN
+ IF (two_section .eqv. .false.) THEN
DO i = src_grid_lon_beg, src_grid_lon_end, stride_lon
p(1) = src_grid_lat(j); p(2) = src_grid_lon(i)
p(:) = p(:)*d2r
- IF(enclosure_cnvx(v, 4, p, co_gc) .EQV. .true.) THEN
+ IF(enclosure_cnvx(v, 4, p, co_gc) .eqv. .true.) THEN
grid_ct = grid_ct+1
- IF (lakestat((j-1)*nlon+i) /= 0) THEN
- lake_ct = lake_ct+1
- IF (lakedpth((j-1)*nlon+i) < 0) THEN
- IF (lakestat((j-1)*nlon+i) == 4) THEN
- lake_dpth_sum = lake_dpth_sum+30.0
- ELSE
- lake_dpth_sum = lake_dpth_sum+100.0
- ENDIF
- ELSE
- lake_dpth_sum = lake_dpth_sum+REAL(lakedpth((j-1)*nlon+i))
- ENDIF
- ENDIF
+ lkst = lakestat((j-1)*nlon+i); lkdp = lakedpth((j-1)*nlon+i)
+ CALL lake_cell_comp(lkst, lkdp, lake_ct, lake_avg_frac, lake_dpth_sum)
ENDIF
ENDDO
ELSE
DO i = src_grid_lon_beg1, src_grid_lon_end1, stride_lon
p(1) = src_grid_lat(j); p(2) = src_grid_lon(i)
p(:) = p(:)*d2r
- IF(enclosure_cnvx(v, 4, p, co_gc) .EQV. .true.) THEN
+ IF(enclosure_cnvx(v, 4, p, co_gc) .eqv. .true.) THEN
grid_ct = grid_ct+1
- IF (lakestat((j-1)*nlon+i) /= 0) THEN
- lake_ct = lake_ct+1
- IF (lakedpth((j-1)*nlon+i) < 0) THEN
- IF (lakestat((j-1)*nlon+i) == 4) THEN
- lake_dpth_sum = lake_dpth_sum+30.0
- ELSE
- lake_dpth_sum = lake_dpth_sum+100.0
- ENDIF
- ELSE
- lake_dpth_sum = lake_dpth_sum+REAL(lakedpth((j-1)*nlon+i))
- ENDIF
- ENDIF
+ lkst = lakestat((j-1)*nlon+i); lkdp = lakedpth((j-1)*nlon+i)
+ CALL lake_cell_comp(lkst, lkdp, lake_ct, lake_avg_frac, lake_dpth_sum)
ENDIF
ENDDO
DO i = src_grid_lon_beg2, src_grid_lon_end2, stride_lon
p(1) = src_grid_lat(j); p(2) = src_grid_lon(i)
p(:) = p(:)*d2r
- IF(enclosure_cnvx(v, 4, p, co_gc) .EQV. .true.) THEN
+ IF(enclosure_cnvx(v, 4, p, co_gc) .eqv. .true.) THEN
grid_ct = grid_ct+1
- IF (lakestat((j-1)*nlon+i) /= 0) THEN
- lake_ct = lake_ct+1
- IF (lakedpth((j-1)*nlon+i) < 0) THEN
- IF (lakestat((j-1)*nlon+i) == 4) THEN
- lake_dpth_sum = lake_dpth_sum+30.0
- ELSE
- lake_dpth_sum = lake_dpth_sum+100.0
- ENDIF
- ELSE
- lake_dpth_sum = lake_dpth_sum+REAL(lakedpth((j-1)*nlon+i))
- ENDIF
- ENDIF
+ lkst = lakestat((j-1)*nlon+i); lkdp = lakedpth((j-1)*nlon+i)
+ CALL lake_cell_comp(lkst, lkdp, lake_ct, lake_avg_frac, lake_dpth_sum)
ENDIF
ENDDO
ENDIF
ENDDO
- cs_lakestat(cs_data_idx)=REAL(lake_ct)/REAL(grid_ct)
+ IF (lakestatus_srce == "GLDBV3" .OR. lakestatus_srce == "GLDBV2" .OR. &
+ lakestatus_srce == "VIIRS" ) THEN
+ cs_lakestat(cs_data_idx)=REAL(lake_ct)/REAL(grid_ct)
+ ENDIF
+ IF (lakestatus_srce == "MODISP") THEN
+ cs_lakestat(cs_data_idx)=lake_avg_frac/REAL(grid_ct)
+ ENDIF
IF (lake_ct /= 0) THEN
cs_lakedpth(cs_data_idx)=lake_dpth_sum/REAL(lake_ct)/10.0 !convert to meter
ELSE
@@ -370,6 +373,44 @@ SUBROUTINE cal_lake_frac_depth(lakestat,cs_lakestat,lakedpth,cs_lakedpth)
END SUBROUTINE cal_lake_frac_depth
+!> Compute cumulatively the lake fraction and lake depth for a cell
+!!
+!! @param[in] lkst lake status value from a grid point in the source data.
+!! @param[in] lkdp lake depth value from a grid point in the source data.
+!! @param[out] lake_ct lake points number accumulated for the cell
+!! @param[out] lake_avg_frac lake fraction value accumulated for the cell.
+!! @param[out] lake_dpth_sum is the lake depth value accumulated for the cell.
+!! @author Ning Wang
+SUBROUTINE lake_cell_comp(lkst, lkdp, lake_ct, lake_avg_frac, lake_dpth_sum)
+ INTEGER*1, INTENT(IN) :: lkst
+ INTEGER*2, INTENT(IN) :: lkdp
+ INTEGER, INTENT(OUT) :: lake_ct
+ REAL*8, INTENT(OUT) :: lake_avg_frac, lake_dpth_sum
+
+ IF (lkst /= 0) THEN ! lake point
+ lake_ct = lake_ct+1
+ IF (lakestatus_srce == "GLDBV3" .OR. lakestatus_srce == "GLDBV2") THEN
+ IF (lkdp <= 0) THEN
+ IF (lkst == 4) THEN
+ lake_dpth_sum = lake_dpth_sum+30.0
+ ELSE
+ lake_dpth_sum = lake_dpth_sum+100.0
+ ENDIF
+ ELSE
+ lake_dpth_sum = lake_dpth_sum+REAL(lkdp)
+ ENDIF
+ ENDIF
+ IF (lakestatus_srce == "MODISP" .OR. lakestatus_srce == "VIIRS") THEN
+ lake_avg_frac = lake_avg_frac + REAL(lkst) / 100.0
+ IF (lkdp <= 0) THEN
+ lake_dpth_sum = lake_dpth_sum+100.0
+ ELSE
+ lake_dpth_sum = lake_dpth_sum+REAL(lkdp)
+ ENDIF
+ ENDIF
+ ENDIF
+END SUBROUTINE lake_cell_comp
+
!> Read the latitude and longitude for a cubed-sphere
!! grid from the 'grid' files. For global grids, all
!! six sides are returned.
@@ -400,7 +441,6 @@ SUBROUTINE read_cubed_sphere_grid(res, grid)
tile_beg = tile_req; tile_end = tile_req
ENDIF
WRITE(res_ch,'(I4)') res
-! gridfile_path = "/scratch1/NCEPDEV/global/glopara/fix/fix_fv3/C"//trim(adjustl(res_ch))//"/"
gridfile_path = "./"
DO i = tile_beg, tile_end
WRITE(ich, '(I1)') i
@@ -521,14 +561,38 @@ SUBROUTINE read_lakedata(lakedata_path,lake_stat,lake_dpth,nlat,nlon)
data_sz = nlon*nlat
- ! read in 30 arc seconds lake data
- lakefile = trim(lakedata_path) // "GlobalLakeStatus.dat"
- OPEN(10, file=lakefile, form='unformatted', access='direct', recl=data_sz*1)
+! read in 30 arc seconds lake data
+ ! lake fraction data
+ lakefile = trim(lakedata_path) // "GlobalLakeStatus_GLDBv3release.dat"
+ IF (lakestatus_srce == "GLDBV2") THEN
+ lakefile = trim(lakedata_path) // "GlobalLakeStatus.dat"
+ ENDIF
+ IF (lakestatus_srce == "GLDBV3") THEN
+ lakefile = trim(lakedata_path) // "GlobalLakeStatus_GLDBv3release.dat"
+ ENDIF
+ IF (lakestatus_srce == "MODISP") THEN
+! lakefile = trim(lakedata_path) // "GlobalLakeStatus_MODIS15s.dat"
+ lakefile = trim(lakedata_path) // "GlobalLakeStatus_MODISp.dat"
+ ENDIF
+ IF (lakestatus_srce == "VIIRS") THEN
+ lakefile = trim(lakedata_path) // "GlobalLakeStatus_VIIRS.dat"
+ ENDIF
+ OPEN(10, file=lakefile, form='unformatted', access='direct', status='old', recl=data_sz*1)
READ(10,rec=1) lake_stat
CLOSE(10)
- lakefile = trim(lakedata_path) // "GlobalLakeDepth.dat"
- OPEN(10, file=lakefile, form='unformatted', access='direct', recl=data_sz*2)
+ ! lake depth data
+ lakefile = trim(lakedata_path) // "GlobalLakeDepth_GLDBv3release.dat"
+ IF (lakedepth_srce == "GLDBV2") THEN
+ lakefile = trim(lakedata_path) // "GlobalLakeDepth.dat"
+ ENDIF
+ IF (lakedepth_srce == "GLDBV3") THEN
+ lakefile = trim(lakedata_path) // "GlobalLakeDepth_GLDBv3release.dat"
+ ENDIF
+ IF (lakedepth_srce == "GLOBATHY") THEN
+ lakefile = trim(lakedata_path) // "GlobalLakeDepth_GLOBathy.dat"
+ ENDIF
+ OPEN(10, file=lakefile, form='unformatted', access='direct', status='old', recl=data_sz*2)
READ(10,rec=1) lake_dpth
CLOSE(10)
@@ -552,7 +616,7 @@ SUBROUTINE write_lakedata_to_orodata(cs_res, cs_lakestat, cs_lakedpth)
INTEGER :: stat, ncid, x_dimid, y_dimid, varid, dimids(2)
INTEGER :: lake_frac_id, lake_depth_id
INTEGER :: land_frac_id, slmsk_id, inland_id, geolon_id, geolat_id
- CHARACTER(len=256) :: filename,string
+ CHARACTER(len=256) :: filename,string,lakeinfo
CHARACTER(len=1) :: ich
CHARACTER(len=4) res_ch
REAL :: lake_frac(cs_res*cs_res),lake_depth(cs_res*cs_res)
@@ -563,7 +627,6 @@ SUBROUTINE write_lakedata_to_orodata(cs_res, cs_lakestat, cs_lakedpth)
INTEGER :: i, j
-! include "netcdf.inc"
tile_sz = cs_res*cs_res
WRITE(res_ch,'(I4)') cs_res
@@ -598,28 +661,51 @@ SUBROUTINE write_lakedata_to_orodata(cs_res, cs_lakestat, cs_lakedpth)
CALL nc_opchk(stat, "nf90_put_att: lake_frac:long_name")
stat = nf90_put_att(ncid, lake_frac_id,'unit','fraction')
CALL nc_opchk(stat, "nf90_put_att: lake_frac:unit")
- write(string,'(a,f5.2)') 'based on GLDBv2 (Choulga et al. 2014); missing lakes &
- added based on land_frac in this dataset; lake_frac cutoff is',lake_cutoff
+ write(lakeinfo,'(a,f4.2,a,i1)') ' lake_frac cutoff=',lake_cutoff,'; binary_lake=',binary_lake
+ IF (lakestatus_srce == "GLDBV3") THEN
+ write(string,'(2a)') 'based on GLDBv3 (Choulga et al. 2019); missing lakes & added based on land_frac in this dataset;', &
+ trim(lakeinfo)
+ ELSE IF (lakestatus_srce == "GLDBV2") THEN
+ write(string,'(2a)') 'based on GLDBv2 (Choulga et al. 2014); missing lakes & added based on land_frac in this dataset;', &
+ trim(lakeinfo)
+ ELSE IF (lakestatus_srce == "MODISP") THEN
+ write(string,'(2a)') 'based on MODIS (2011-2015) product updated with two &
+ Landsat products: the JRC water product (2016-2020) and the GLC-FCS30 (2020); &
+ the source data set was created by Chengquan Huang of UMD;',trim(lakeinfo)
+ ELSE IF (lakestatus_srce == "VIIRS") THEN
+ write(string,'(2a)') 'based on multi-year VIIRS global surface type &
+ classification map (2012-2019); the source data set was created by &
+ Chengquan Huang of UMD and Michael Barlage of NOAA;',trim(lakeinfo)
+ ENDIF
stat = nf90_put_att(ncid, lake_frac_id,'description',trim(string))
CALL nc_opchk(stat, "nf90_put_att: lake_frac:description")
#endif
stat = nf90_def_var(ncid,"lake_depth",NF90_FLOAT,dimids,lake_depth_id)
CALL nc_opchk(stat, "nf90_def_var: lake_depth")
#ifdef ADD_ATT_FOR_NEW_VAR
- stat = nf90_put_att(ncid, lake_depth_id,'coordinates','geolon geolat')
- CALL nc_opchk(stat, "nf90_put_att: lake_depth:coordinates")
+ stat = nf90_put_att(ncid, lake_depth_id,'coordinates','geolon geolat')
+ CALL nc_opchk(stat, "nf90_put_att: lake_depth:coordinates")
stat = nf90_put_att(ncid, lake_depth_id,'long_name','lake depth')
CALL nc_opchk(stat, "nf90_put_att: lake_depth:long_name")
stat = nf90_put_att(ncid, lake_depth_id,'unit','meter')
CALL nc_opchk(stat, "nf90_put_att: lake_depth:long_name")
- stat = nf90_put_att(ncid, lake_depth_id,'description', &
+ IF (lakedepth_srce == "GLDBV3") THEN
+ stat = nf90_put_att(ncid, lake_depth_id,'description', &
+ 'based on GLDBv3 (Choulga et al. 2019); missing depth set to 10m &
+ (except to 211m in Caspian Sea); spurious large pos. depths are left unchanged.')
+ ELSE IF (lakedepth_srce == "GLDBV2") THEN
+ stat = nf90_put_att(ncid, lake_depth_id,'description', &
'based on GLDBv2 (Choulga et al. 2014); missing depth set to 10m &
(except to 211m in Caspian Sea); spurious large pos. depths are left unchanged.')
+ ELSE IF (lakedepth_srce == "GLOBATHY") THEN
+ stat = nf90_put_att(ncid, lake_depth_id,'description', &
+ 'based on GLOBathy data resampled and projected to the MODIS domain.')
+ ENDIF
CALL nc_opchk(stat, "nf90_put_att: lake_depth:description")
#endif
- write(string,'(a,es8.1)') 'land_frac and lake_frac are adjusted such that their sum '// &
- 'is 1 at points where inland=1; land_frac cutoff is',land_cutoff
+ write(string,'(a,es8.1)') 'land_frac and lake_frac are adjusted such that &
+ their sum is 1 at points where inland=1; land_frac cutoff is',land_cutoff
stat = nf90_put_att(ncid, land_frac_id,'description',trim(string))
CALL nc_opchk(stat, "nf90_put_att: land_frac:description")
@@ -660,45 +746,40 @@ SUBROUTINE write_lakedata_to_orodata(cs_res, cs_lakestat, cs_lakedpth)
lake_frac (:) = cs_lakestat ((tile_num-1)*tile_sz+1:tile_num*tile_sz)
lake_depth(:) = cs_lakedepth((tile_num-1)*tile_sz+1:tile_num*tile_sz)
-! add Caspian Sea and Aral Sea to lake_frac and lake_depth
- IF (tile_num == 2 .or. tile_num == 3) THEN
- DO i = 1, tile_sz
- IF (land_frac(i) < 0.9 .AND. lake_frac(i) < 0.1) THEN
- IF (geolat(i) > 35.0 .AND. geolat(i) <= 50.0 .AND. &
- geolon(i) > 45.0 .AND. geolon(i) <= 55.0) THEN
- lake_frac(i) = 1.-land_frac(i)
- lake_depth(i) = 211.0
- ENDIF
- IF (geolat(i) > 35.0 .AND. geolat(i) <= 50.0 .AND. &
- geolon(i) > 57.0 .AND. geolon(i) <= 63.0) THEN
- lake_frac(i) = 1.-land_frac(i)
- lake_depth(i) = 10.0
- ENDIF
- ENDIF
- ENDDO
+! include Caspian Sea and Aral Sea if GLDB data set is used, and
+! exclude lakes in the coastal areas of Antarctica if MODIS data set is used
+ CALL include_exclude_lakes(lake_frac,land_frac,lake_depth,geolat,geolon,tile_num)
+
+! epsil is "numerical" nonzero min for lake_frac/land_frac
+! lake_cutoff/land_cutoff is practical min for lake_frac/land_frac
+ IF (min(lake_cutoff,land_cutoff) < epsil) then
+ PRINT *,'lake_cutoff/land_cutoff cannot be smaller than epsil, reset...'
+ lake_cutoff=max(epsil,lake_cutoff)
+ land_cutoff=max(epsil,land_cutoff)
ENDIF
! adjust land_frac and lake_frac, and make sure land_frac+lake_frac=1 at inland points
DO i = 1, tile_sz
- if (lake_frac(i) >= lake_cutoff) then ! non-zero lake_frac dominates over land_frac
- land_frac(i) = max(0., min(1., 1.-lake_frac(i)))
- elseif (inland(i) == 1.) then ! land_frac dominates over lake_frac at inland points
- lake_frac(i) = max(0., min(1., 1.-land_frac(i)))
- end if
+ if (land_frac(i)< land_cutoff) land_frac(i)=0.
+ if (land_frac(i)>1.-land_cutoff) land_frac(i)=1.
-! epsil is "numerical" nonzero min for lake_frac/land_frac
-! lake_cutoff/land_cutoff is practical min for lake_frac/land_frac
- if (min(lake_cutoff,land_cutoff) < epsil) then
- print *,'lake_cutoff/land_cutoff cannot be smaller than epsil, reset...'
- lake_cutoff=max(epsil,lake_cutoff)
- land_cutoff=max(epsil,land_cutoff)
+ if (inland(i) /= 1.) then
+ lake_frac(i) = 0.
+ endif
+
+ if (lake_frac(i) < lake_cutoff) then
+ lake_frac(i)=0.
+ elseif (binary_lake == 1) then
+ lake_frac(i)=1.
end if
+ if (lake_frac(i) > 1.-epsil) lake_frac(i)=1.
+ ENDDO
- if (lake_frac(i)< lake_cutoff) lake_frac(i)=0.
- if (lake_frac(i)>1.-lake_cutoff) lake_frac(i)=1.
- if (inland(i) == 1.) land_frac(i) = 1.-lake_frac(i)
- if (land_frac(i)< land_cutoff) land_frac(i)=0.
- if (land_frac(i)>1.-land_cutoff) land_frac(i)=1.
+! finalize land_frac/slmsk based on modified lake_frac
+ DO i = 1, tile_sz
+ if (inland(i) == 1.) then
+ land_frac(i) = 1. - lake_frac(i)
+ end if
if (lake_frac(i) < lake_cutoff) then
lake_depth(i)=0.
@@ -707,6 +788,7 @@ SUBROUTINE write_lakedata_to_orodata(cs_res, cs_lakestat, cs_lakedpth)
end if
slmsk(i) = nint(land_frac(i))
ENDDO
+
! write 2 new variables
stat = nf90_put_var(ncid, lake_frac_id, lake_frac, &
start = (/ 1, 1 /), count = (/ cs_res, cs_res /) )
@@ -794,43 +876,65 @@ SUBROUTINE write_reg_lakedata_to_orodata(cs_res, tile_x_dim, tile_y_dim, cs_lake
CALL nc_opchk(stat, "nf90_redef")
IF (nf90_inq_varid(ncid, "lake_frac",lake_frac_id) /= 0) THEN
- stat = nf90_def_var(ncid,"lake_frac",NF90_FLOAT,dimids,lake_frac_id)
- CALL nc_opchk(stat, "nf90_def_var: lake_frac")
+ stat = nf90_def_var(ncid,"lake_frac",NF90_FLOAT,dimids,lake_frac_id)
+ CALL nc_opchk(stat, "nf90_def_var: lake_frac")
#ifdef ADD_ATT_FOR_NEW_VAR
- stat = nf90_put_att(ncid, lake_frac_id,'coordinates','geolon geolat')
- CALL nc_opchk(stat, "nf90_put_att: lake_frac:coordinates")
- stat = nf90_put_att(ncid, lake_frac_id,'long_name','lake fraction')
- CALL nc_opchk(stat, "nf90_put_att: lake_frac:long_name")
- stat = nf90_put_att(ncid, lake_frac_id,'unit','fraction')
- CALL nc_opchk(stat, "nf90_put_att: lake_frac:unit")
- stat = nf90_put_att(ncid, lake_frac_id,'description', &
- 'based on GLDBv2 (Choulga et al. 2014); missing lakes &
- added based on land_frac in this dataset.')
- CALL nc_opchk(stat, "nf90_put_att: lake_frac:description")
+ stat = nf90_put_att(ncid, lake_frac_id,'coordinates','geolon geolat')
+ CALL nc_opchk(stat, "nf90_put_att: lake_frac:coordinates")
+ stat = nf90_put_att(ncid, lake_frac_id,'long_name','lake fraction')
+ CALL nc_opchk(stat, "nf90_put_att: lake_frac:long_name")
+ stat = nf90_put_att(ncid, lake_frac_id,'unit','fraction')
+ CALL nc_opchk(stat, "nf90_put_att: lake_frac:unit")
+ IF (lakestatus_srce == "GLDBV3") THEN
+ write(string,'(a,es8.1)') 'based on GLDBv3 (Choulga et al. 2019); missing lakes &
+ added based on land_frac in this dataset; lake_frac cutoff:',lake_cutoff
+ ELSE IF (lakestatus_srce == "GLDBV2") THEN
+ write(string,'(a,es8.1)') 'based on GLDBv2 (Choulga et al. 2014); missing lakes &
+ added based on land_frac in this dataset; lake_frac cutoff:',lake_cutoff
+ ELSE IF (lakestatus_srce == "MODISP") THEN
+ write(string,'(a,es8.1)') 'based on MODIS (2011-2015) product updated with two &
+ Landsat products: the JRC water product (2016-2020) and the GLC-FCS30 (2020); &
+ the source data set was created by Chengquan Huang of UMD; &
+ lake_frac cutoff:',lake_cutoff
+ ELSE IF (lakestatus_srce == "VIIRS") THEN
+ write(string,'(a,es8.1)') 'based on multi-year VIIRS global surface type &
+ classification map (2012-2019); the source data set was created by &
+ Chengquan Huang of UMD and Michael Barlage of NOAA; &
+ lake_frac cutoff:',lake_cutoff
+ ENDIF
+ stat = nf90_put_att(ncid, lake_frac_id,'description',trim(string))
+ CALL nc_opchk(stat, "nf90_put_att: lake_frac:description")
#endif
ENDIF
IF (nf90_inq_varid(ncid, "lake_depth",lake_depth_id) /= 0) THEN
- stat = nf90_def_var(ncid,"lake_depth",NF90_FLOAT,dimids,lake_depth_id)
- CALL nc_opchk(stat, "nf90_def_var: lake_depth")
+ stat = nf90_def_var(ncid,"lake_depth",NF90_FLOAT,dimids,lake_depth_id)
+ CALL nc_opchk(stat, "nf90_def_var: lake_depth")
#ifdef ADD_ATT_FOR_NEW_VAR
- stat = nf90_put_att(ncid, lake_depth_id,'coordinates','geolon geolat')
- CALL nc_opchk(stat, "nf90_put_att: lake_depth:coordinates")
- stat = nf90_put_att(ncid, lake_depth_id,'long_name','lake depth')
- CALL nc_opchk(stat, "nf90_put_att: lake_depth:long_name")
- stat = nf90_put_att(ncid, lake_depth_id,'unit','meter')
- CALL nc_opchk(stat, "nf90_put_att: lake_depth:long_name")
- stat = nf90_put_att(ncid, lake_depth_id,'description', &
- 'based on GLDBv2 (Choulga et al. 2014); missing depth set to 10m &
- (except to 211m in Caspian Sea); spurious large pos. depths are left unchanged.')
- CALL nc_opchk(stat, "nf90_put_att: lake_depth:description")
-#endif
+ stat = nf90_put_att(ncid, lake_depth_id,'coordinates','geolon geolat')
+ CALL nc_opchk(stat, "nf90_put_att: lake_depth:coordinates")
+ stat = nf90_put_att(ncid, lake_depth_id,'long_name','lake depth')
+ CALL nc_opchk(stat, "nf90_put_att: lake_depth:long_name")
+ stat = nf90_put_att(ncid, lake_depth_id,'unit','meter')
+ CALL nc_opchk(stat, "nf90_put_att: lake_depth:long_name")
+ IF (lakedepth_srce == "GLDBV3") THEN
+ stat = nf90_put_att(ncid, lake_depth_id,'description', &
+ 'based on GLDBv3 (Choulga et al. 2019); missing depth set to 10m &
+ (except to 211m in Caspian Sea); spurious large pos. depths are left unchanged.')
+ ELSE IF (lakedepth_srce == "GLDBV2") THEN
+ stat = nf90_put_att(ncid, lake_depth_id,'description', &
+ 'based on GLDBv2 (Choulga et al. 2014); missing depth set to 10m &
+ (except to 211m in Caspian Sea); spurious large pos. depths are left unchanged.')
+ ELSE IF (lakedepth_srce == "GLOBATHY") THEN
+ stat = nf90_put_att(ncid, lake_depth_id,'description', &
+ 'based on GLOBathy data resampled and projected to the MODIS domain.')
+ ENDIF
+ CALL nc_opchk(stat, "nf90_put_att: lake_depth:description")
ENDIF
- write(string,'(a,es8.1)') 'land_frac and lake_frac are adjusted '// &
- 'such that their sum is 1 at points where inland=1; land_frac '// &
- 'cutoff is ',land_cutoff
+#endif
+ write(string,'(a,es8.1)') 'land_frac and lake_frac are adjusted such that &
+ their sum is 1 at points where inland=1; land_frac cutoff is',land_cutoff
stat = nf90_put_att(ncid, land_frac_id,'description',trim(string))
CALL nc_opchk(stat, "nf90_put_att: land_frac:description")
-
write(string,'(a)') 'slmsk = nint(land_frac)'
stat = nf90_put_att(ncid, slmsk_id,'description',trim(string))
CALL nc_opchk(stat, "nf90_put_att: slmsk:description")
@@ -870,44 +974,36 @@ SUBROUTINE write_reg_lakedata_to_orodata(cs_res, tile_x_dim, tile_y_dim, cs_lake
lake_frac(:) = cs_lakestat((tile_num-1)*tile_sz+1:tile_num*tile_sz)
lake_depth(:) = cs_lakedepth((tile_num-1)*tile_sz+1:tile_num*tile_sz)
-! add Caspian Sea and Aral Sea to lake_frac and lake_depth
- DO i = 1, tile_sz
- IF (land_frac(i) < 0.9 .AND. lake_frac(i) < 0.1) THEN
- IF (geolat(i) > 35.0 .AND. geolat(i) <= 50.0 .AND. &
- geolon(i) > 45.0 .AND. geolon(i) <= 55.0) THEN
- lake_frac(i) = 1.-land_frac(i)
- lake_depth(i) = 211.0
- ENDIF
- IF (geolat(i) > 35.0 .AND. geolat(i) <= 50.0 .AND. &
- geolon(i) > 57.0 .AND. geolon(i) <= 63.0) THEN
- lake_frac(i) = 1.-land_frac(i)
- lake_depth(i) = 10.0
- ENDIF
- ENDIF
- ENDDO
-
-! adjust land_frac and lake_frac, and make sure land_frac+lake_frac=1 at inland points
- DO i = 1, tile_sz
- if (lake_frac(i) >= lake_cutoff) then ! non-zero lake_frac dominates over land_frac
- land_frac(i) = max(0., min(1., 1.-lake_frac(i)))
- elseif (inland(i) == 1.) then ! land_frac dominates over lake_frac at inland points
- lake_frac(i) = max(0., min(1., 1.-land_frac(i)))
- end if
+! include Caspian Sea and Aral Sea if GLDB data set is used, and
+! exclude lakes in the coastal areas of Antarctica if MODIS data set is used
+ CALL include_exclude_lakes(lake_frac,land_frac,lake_depth,geolat,geolon,tile_num)
! epsil is "numerical" nonzero min for lake_frac/land_frac
! lake_cutoff/land_cutoff is practical min for lake_frac/land_frac
- if (min(lake_cutoff,land_cutoff) < epsil) then
+ IF (min(lake_cutoff,land_cutoff) < epsil) then
print *,'lake_cutoff/land_cutoff cannot be smaller than epsil, reset...'
lake_cutoff=max(epsil,lake_cutoff)
land_cutoff=max(epsil,land_cutoff)
- end if
+ ENDIF
- if (lake_frac(i)< lake_cutoff) lake_frac(i)=0.
- if (lake_frac(i)>1.-lake_cutoff) lake_frac(i)=1.
- if (inland(i) == 1.) land_frac(i) = 1.-lake_frac(i)
+! adjust land_frac and lake_frac, and make sure land_frac+lake_frac=1 at inland points
+ DO i = 1, tile_sz
if (land_frac(i)< land_cutoff) land_frac(i)=0.
if (land_frac(i)>1.-land_cutoff) land_frac(i)=1.
+ if (inland(i) /= 1.) then
+ lake_frac(i) = 0.
+ endif
+
+ if (lake_frac(i) < lake_cutoff) lake_frac(i)=0.
+ if (lake_frac(i) > 1.-epsil) lake_frac(i)=1.
+ ENDDO
+
+ DO i = 1, tile_sz
+ if (inland(i) == 1.) then
+ land_frac(i) = 1. - lake_frac(i)
+ end if
+
if (lake_frac(i) < lake_cutoff) then
lake_depth(i)=0.
elseif (lake_frac(i) >= lake_cutoff .and. lake_depth(i)==0.) then
@@ -937,12 +1033,76 @@ SUBROUTINE write_reg_lakedata_to_orodata(cs_res, tile_x_dim, tile_y_dim, cs_lake
stat = nf90_close(ncid)
CALL nc_opchk(stat, "nf90_close")
- DEALLOCATE(lake_frac, lake_depth)
- DEALLOCATE(geolon, geolat)
- DEALLOCATE(land_frac, slmsk)
-
END SUBROUTINE write_reg_lakedata_to_orodata
+!> Include Caspian Sea and Aral Sea if GLDB dataset is used, and
+!! exclude lakes in the coastal areas of Antarctica if MODIS dataset is used.
+!!
+!! @param[inout] lake_frac lake fraction array of the given tile.
+!! @param[inout] lake_depth lake depth array of the given tile.
+!! @param[in] land_frac land fraction array of the given tile.
+!! @param[in] geolat latitude array of the given tile.
+!! @param[in] geolon longitude array of the given tile.
+!! @param[in] tile_num tile number of the given tile.
+!! @author Ning Wang
+SUBROUTINE include_exclude_lakes(lake_frac,land_frac,lake_depth,geolat,geolon,tile_num)
+ REAL, INTENT(INOUT) :: lake_frac(cs_res*cs_res), lake_depth(cs_res*cs_res)
+ REAL, INTENT(IN) :: land_frac(cs_res*cs_res)
+ REAL, INTENT(IN) :: geolat(cs_res*cs_res), geolon(cs_res*cs_res)
+ INTEGER, INTENT(IN) :: tile_num
+
+ INTEGER :: tile_sz
+
+ tile_sz = cs_res*cs_res
+! add Caspian Sea and Aral Sea
+ IF (tile_num == 2 .OR. tile_num == 3 .OR. tile_num == 7) THEN
+ IF (lakedepth_srce == "GLDBV3" .OR. lakedepth_srce == "GLDBV2") THEN
+ IF (lakestatus_srce == "GLDBV3" .OR. lakestatus_srce == "GLDBV2") THEN
+ DO i = 1, tile_sz
+ IF (land_frac(i) < 0.9 .AND. lake_frac(i) < 0.1) THEN
+ IF (geolat(i) > 35.0 .AND. geolat(i) <= 50.0 .AND. &
+ geolon(i) > 45.0 .AND. geolon(i) <= 55.0) THEN
+ lake_frac(i) = 1.-land_frac(i)
+ lake_depth(i) = 211.0
+ ENDIF
+ IF (geolat(i) > 35.0 .AND. geolat(i) <= 50.0 .AND. &
+ geolon(i) > 57.0 .AND. geolon(i) <= 63.0) THEN
+ lake_frac(i) = 1.-land_frac(i)
+ lake_depth(i) = 10.0
+ ENDIF
+ ENDIF
+ ENDDO
+ ENDIF
+ IF (lakestatus_srce == "MODISP" .OR. lakestatus_srce == "VIIRS") THEN
+ DO i = 1, tile_sz
+ IF (land_frac(i) < 0.9) THEN
+ IF (geolat(i) > 35.0 .AND. geolat(i) <= 50.0 .AND. &
+ geolon(i) > 45.0 .AND. geolon(i) <= 55.0) THEN
+ lake_depth(i) = 211.0
+ ENDIF
+ IF (geolat(i) > 35.0 .AND. geolat(i) <= 50.0 .AND. &
+ geolon(i) > 57.0 .AND. geolon(i) <= 63.0) THEN
+ lake_depth(i) = 10.0
+ ENDIF
+ ENDIF
+ ENDDO
+ ENDIF
+ ENDIF
+ ENDIF
+! remove lakes below 60 deg south
+ IF (tile_num == 6) THEN
+ IF (lakestatus_srce == "MODISP" .OR. lakestatus_srce == "VIIRS") THEN
+ DO i = 1, tile_sz
+ IF (geolat(i) < -60.0) THEN
+ lake_frac(i) = 0.0
+ lake_depth(i) = 0.0
+ ENDIF
+ ENDDO
+ ENDIF
+ ENDIF
+
+END SUBROUTINE include_exclude_lakes
+
!> Check NetCDF error code
!!
!! @param[in] stat Error code.
@@ -958,7 +1118,7 @@ SUBROUTINE nc_opchk(stat,opname)
IF (stat .NE.0) THEN
msg = trim(opname) // ' Error, status code and message:'
PRINT*,trim(msg), stat, nf90_strerror(stat)
- STOP
+ STOP -1
END IF
END SUBROUTINE nc_opchk
diff --git a/ush/fv3gfs_driver_grid.sh b/ush/fv3gfs_driver_grid.sh
index 9347749f0..81ac33551 100755
--- a/ush/fv3gfs_driver_grid.sh
+++ b/ush/fv3gfs_driver_grid.sh
@@ -47,9 +47,9 @@ export res=${res:-96} # resolution of tile: 48, 96, 128, 192, 384, 768
export gtype=${gtype:-uniform} # grid type: uniform, stretch, nest, regional_gfdl,
# or regional_esg
-export add_lake=${add_lake:-false} # add lake fraction and depth. uniform only.
-export lake_cutoff=${lake_cutoff:-0.20} # lake fractions less than lake_cutoff
- # are ignored.
+export add_lake=${add_lake:-false} # add lake fraction and depth. uniform only.
+export lake_cutoff=${lake_cutoff:-0.50} # return 0 if lake_frac < lake_cutoff & add_lake=T
+export binary_lake=${binary_lake:-1} # return 1 if lake_frac >= lake_cutoff & add_lake=T
export make_gsl_orog=${make_gsl_orog:-false} # when true, create GSL drag suite orog files.
diff --git a/ush/fv3gfs_make_lake.sh b/ush/fv3gfs_make_lake.sh
index cfb12aba6..f8f293587 100755
--- a/ush/fv3gfs_make_lake.sh
+++ b/ush/fv3gfs_make_lake.sh
@@ -13,6 +13,27 @@ if [ $gtype != uniform ] && [ $gtype != regional_gfdl ]; then
echo "lakefrac has only been implemented for 'uniform' and 'regional_gfdl'."
exit 0
fi
+echo "lake_data_srce = $lake_data_srce"
+if [ $lake_data_srce == MODISP_GLDBV3 ]; then
+ lakestatusrc="MODISP"
+ lakedepthsrc="GLDBV3"
+fi
+if [ $lake_data_srce == MODISP_GLOBATHY ]; then
+ lakestatusrc="MODISP"
+ lakedepthsrc="GLOBATHY"
+fi
+if [ $lake_data_srce == VIIRS_GLDBV3 ]; then
+ lakestatusrc="VIIRS"
+ lakedepthsrc="GLDBV3"
+fi
+if [ $lake_data_srce == VIIRS_GLOBATHY ]; then
+ lakestatusrc="VIIRS"
+ lakedepthsrc="GLOBATHY"
+fi
+if [ $lake_data_srce == GLDBV3 ]; then
+ lakestatusrc="GLDBV3"
+ lakedepthsrc="GLDBV3"
+fi
exe_add_lake=$exec_dir/lakefrac
if [ ! -s $exe_add_lake ]; then
@@ -54,7 +75,7 @@ if [ $gtype == uniform ]; then
done
fi
-if [ $gtype == regional_gfdl ]; then
+if [ $gtype == regional_gfdl ] || [ $gtype == regional_esg ]; then
tile_beg=7
tile_end=7
tile=7
@@ -66,7 +87,7 @@ fi
# create inland mask and save it to the orography files
-cutoff=0.99
+cutoff=0.75
rd=7
if [ $gtype == uniform ]; then
$APRUN $exe_inland $res $cutoff $rd g
@@ -74,6 +95,9 @@ fi
if [ $gtype == regional_gfdl ]; then
$APRUN $exe_inland $res $cutoff $rd r
fi
+if [ $gtype == regional_esg ]; then
+ $APRUN $exe_inland $res $cutoff $rd r
+fi
err=$?
if [ $err != 0 ]; then
set +x
@@ -81,12 +105,12 @@ if [ $err != 0 ]; then
exit $err
fi
-# create lake data for FV3 grid and save it to the orography files
+# create fractional lake data for FV3 grid and save it to the orography files
tile=$tile_beg
while [ $tile -le $tile_end ]; do
outfile=oro.C${res}.tile${tile}.nc
- $APRUN $exe_add_lake ${tile} ${res} ${indir} ${lake_cutoff}
+ $APRUN $exe_add_lake ${tile} ${res} ${indir} ${lakestatusrc} ${lakedepthsrc} ${lake_cutoff} ${binary_lake}
err=$?
if [ $err != 0 ]; then
set +x
From 892b693ba49b37c23f08cc8e18550ba72e108762 Mon Sep 17 00:00:00 2001
From: David Huber <69919478+DavidHuber-NOAA@users.noreply.github.com>
Date: Tue, 14 Nov 2023 08:05:22 -0500
Subject: [PATCH 2/3] Upgrade libraries to spack-stack/1.5.0. (#866)
Update libraries to match those used by UFS. Done for
Hera, Jet and Orion.
Fixes #859.
---
ci/spack.yaml | 8 +--
cmake/mpiexec.jet | 2 +-
modulefiles/build.hera.gnu.lua | 51 ++++++++++---------
modulefiles/build.hera.intel.lua | 33 ++++++-------
modulefiles/build.jet.intel.lua | 70 +++++++++++++--------------
modulefiles/build.orion.intel.lua | 38 +++++++--------
reg_tests/chgres_cube/driver.orion.sh | 2 +-
reg_tests/cpld_gridgen/rt.sh | 2 +-
util/gdas_init/driver.jet.sh | 3 ++
9 files changed, 104 insertions(+), 105 deletions(-)
diff --git a/ci/spack.yaml b/ci/spack.yaml
index 0549a8345..8711ee2cc 100644
--- a/ci/spack.yaml
+++ b/ci/spack.yaml
@@ -4,14 +4,14 @@ spack:
all:
compiler: [intel, gcc@10:10, apple-clang@14]
specs:
- - netcdf-c@4.7.4
- - netcdf-fortran@4.5.3
+ - netcdf-c@4.9.2
+ - netcdf-fortran@4.6.0
- bacio@2.4.1
- g2@3.4.5
- - ip@3.3.3
+ - ip@4.4.0 precision=d
- nemsio@2.5.4
- sp@2.3.3
- - w3emc@2.9.2
+ - w3emc@2.10.0
- sfcio@1.4.1
- sigio@2.3.2
- nccmp@1.9.0.1
diff --git a/cmake/mpiexec.jet b/cmake/mpiexec.jet
index a59fbcbd9..b5813d4fe 100755
--- a/cmake/mpiexec.jet
+++ b/cmake/mpiexec.jet
@@ -7,7 +7,7 @@
#
ACCOUNT=nesdis-rdo2
-QOS=debug
+QOS=batch
PARTITION=xjet
NP=$1
diff --git a/modulefiles/build.hera.gnu.lua b/modulefiles/build.hera.gnu.lua
index d3bd08e3d..1c5d0835a 100644
--- a/modulefiles/build.hera.gnu.lua
+++ b/modulefiles/build.hera.gnu.lua
@@ -2,31 +2,21 @@ help([[
Load environment to compile UFS_UTILS on Hera using Gnu
]])
-cmake_ver=os.getenv("cmake_ver") or "3.20.1"
-load(pathJoin("cmake", cmake_ver))
-
hpss_ver=os.getenv("hpss_ver") or ""
load(pathJoin("hpss", hpss_ver))
-prepend_path("MODULEPATH", "/scratch1/NCEPDEV/nems/role.epic/hpc-stack/libs/gnu-9.2/modulefiles/stack")
-
-gnu_ver=os.getenv("gnu_ver") or "9.2"
-load(pathJoin("gnu", gnu_ver))
+prepend_path("MODULEPATH", "/scratch1/NCEPDEV/nems/role.epic/spack-stack/spack-stack-1.5.0/envs/unified-env-noavx512/install/modulefiles/Core")
+-- For openmpi:
+prepend_path("MODULEPATH", "/scratch1/NCEPDEV/jcsda/jedipara/spack-stack/modulefiles")
-hpc_ver=os.getenv("hpc_ver") or "1.2.0"
-load(pathJoin("hpc", hpc_ver))
+stack_gcc_ver=os.getenv("stack_gcc_ver") or "9.2"
+load(pathJoin("stack-gcc", gnu_ver))
-hpc_gnu_ver=os.getenv("hpc_gnu_ver") or "9.2"
-load(pathJoin("hpc-gnu", hpc_gnu_ver))
+stack_openmpi_ver=os.getenv("stack_openmpi_ver") or "4.1.5"
+load(pathJoin("stack-openmpi", stack_openmpi_ver))
-hpc_mpich_ver=os.getenv("hpc_mpich_ver") or "3.3.2"
-load(pathJoin("hpc-mpich", hpc_mpich_ver))
-
-netcdf_ver=os.getenv("netcdf_ver") or "4.9.1"
-load(pathJoin("netcdf", netcdf_ver))
-
-esmf_ver=os.getenv("esmf_ver") or "8.4.1b07"
-load(pathJoin("esmf", esmf_ver))
+cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+load(pathJoin("cmake", cmake_ver))
bacio_ver=os.getenv("bacio_ver") or "2.4.1"
load(pathJoin("bacio", bacio_ver))
@@ -34,7 +24,7 @@ load(pathJoin("bacio", bacio_ver))
g2_ver=os.getenv("g2_ver") or "3.4.5"
load(pathJoin("g2", g2_ver))
-ip_ver=os.getenv("ip_ver") or "4.0.0"
+ip_ver=os.getenv("ip_ver") or "4.3.0"
load(pathJoin("ip", ip_ver))
nemsio_ver=os.getenv("nemsio_ver") or "2.5.4"
@@ -43,7 +33,7 @@ load(pathJoin("nemsio", nemsio_ver))
sp_ver=os.getenv("sp_ver") or "2.3.3"
load(pathJoin("sp", sp_ver))
-w3emc_ver=os.getenv("w3emc_ver") or "2.9.2"
+w3emc_ver=os.getenv("w3emc_ver") or "2.10.0"
load(pathJoin("w3emc", w3emc_ver))
sfcio_ver=os.getenv("sfcio_ver") or "1.4.1"
@@ -52,13 +42,22 @@ load(pathJoin("sfcio", sfcio_ver))
sigio_ver=os.getenv("sigio_ver") or "2.3.2"
load(pathJoin("sigio", sigio_ver))
-nccmp_ver=os.getenv("nccmp_ver") or "1.9.1.0"
+hdf5_ver=os.getenv("hdf5_ver") or "1.14.0"
+load(pathJoin("hdf5", hdf5_ver))
+
+netcdf_c_ver=os.getenv("netcdf_c_ver") or "4.9.2"
+load(pathJoin("netcdf-c", netcdf_c_ver))
+
+netcdf_fortran_ver=os.getenv("netcdf_fortran_ver") or "4.6.0"
+load(pathJoin("netcdf-fortran", netcdf_fortran_ver))
+
+nccmp_ver=os.getenv("nccmp_ver") or "1.9.0.1"
load(pathJoin("nccmp", nccmp_ver))
-zlib_ver=os.getenv("zlib_ver") or "1.2.12"
-load(pathJoin("zlib", zlib_ver))
+esmf_ver=os.getenv("esmf_ver") or "8.4.2"
+load(pathJoin("esmf", esmf_ver))
-png_ver=os.getenv("png_ver") or "1.6.37"
-load(pathJoin("libpng", png_ver))
+nco_ver=os.getenv("nco_ver") or "5.0.6"
+load(pathJoin("nco", nco_ver))
whatis("Description: UFS_UTILS build environment")
diff --git a/modulefiles/build.hera.intel.lua b/modulefiles/build.hera.intel.lua
index bf92b2634..016c35ff3 100644
--- a/modulefiles/build.hera.intel.lua
+++ b/modulefiles/build.hera.intel.lua
@@ -2,22 +2,19 @@ help([[
Load environment to compile UFS_UTILS on Hera using Intel
]])
-cmake_ver=os.getenv("cmake_ver") or "3.20.1"
-load(pathJoin("cmake", cmake_ver))
-
hpss_ver=os.getenv("hpss_ver") or ""
load(pathJoin("hpss", hpss_ver))
-prepend_path("MODULEPATH", "/scratch1/NCEPDEV/nems/role.epic/hpc-stack/libs/intel-2022.1.2/modulefiles/stack")
+prepend_path("MODULEPATH", "/scratch1/NCEPDEV/nems/role.epic/spack-stack/spack-stack-1.5.0/envs/unified-env-noavx512/install/modulefiles/Core")
-hpc_ver=os.getenv("hpc_ver") or "1.2.0"
-load(pathJoin("hpc", hpc_ver))
+stack_intel_ver=os.getenv("stack_intel_ver") or "2021.5.0"
+load(pathJoin("stack-intel", stack_intel_ver))
-hpc_intel_ver=os.getenv("hpc_intel_ver") or "2022.1.2"
-load(pathJoin("hpc-intel", hpc_intel_ver))
+stack_impi_ver=os.getenv("stack_impi_ver") or "2021.5.1"
+load(pathJoin("stack-intel-oneapi-mpi", stack_impi_ver))
-hpc_impi_ver=os.getenv("hpc_impi_ver") or "2022.1.2"
-load(pathJoin("hpc-impi", hpc_impi_ver))
+cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+load(pathJoin("cmake", cmake_ver))
bacio_ver=os.getenv("bacio_ver") or "2.4.1"
load(pathJoin("bacio", bacio_ver))
@@ -25,7 +22,7 @@ load(pathJoin("bacio", bacio_ver))
g2_ver=os.getenv("g2_ver") or "3.4.5"
load(pathJoin("g2", g2_ver))
-ip_ver=os.getenv("ip_ver") or "4.0.0"
+ip_ver=os.getenv("ip_ver") or "4.3.0"
load(pathJoin("ip", ip_ver))
nemsio_ver=os.getenv("nemsio_ver") or "2.5.4"
@@ -34,7 +31,7 @@ load(pathJoin("nemsio", nemsio_ver))
sp_ver=os.getenv("sp_ver") or "2.3.3"
load(pathJoin("sp", sp_ver))
-w3emc_ver=os.getenv("w3emc_ver") or "2.9.2"
+w3emc_ver=os.getenv("w3emc_ver") or "2.10.0"
load(pathJoin("w3emc", w3emc_ver))
sfcio_ver=os.getenv("sfcio_ver") or "1.4.1"
@@ -43,22 +40,22 @@ load(pathJoin("sfcio", sfcio_ver))
sigio_ver=os.getenv("sigio_ver") or "2.3.2"
load(pathJoin("sigio", sigio_ver))
-zlib_ver=os.getenv("zlib_ver") or "1.2.12"
+zlib_ver=os.getenv("zlib_ver") or "1.2.13"
load(pathJoin("zlib", zlib_ver))
png_ver=os.getenv("png_ver") or "1.6.37"
load(pathJoin("libpng", png_ver))
-hdf5_ver=os.getenv("hdf5_ver") or "1.14.0"
-load(pathJoin("hdf5", hdf5_ver))
+netcdf_c_ver=os.getenv("netcdf_c_ver") or "4.9.2"
+load(pathJoin("netcdf-c", netcdf_c_ver))
-netcdf_ver=os.getenv("netcdf_ver") or "4.9.1"
-load(pathJoin("netcdf", netcdf_ver))
+netcdf_fortran_ver=os.getenv("netcdf_fortran_ver") or "4.6.0"
+load(pathJoin("netcdf-fortran", netcdf_fortran_ver))
nccmp_ver=os.getenv("nccmp_ver") or "1.9.0.1"
load(pathJoin("nccmp", nccmp_ver))
-esmf_ver=os.getenv("esmf_ver") or "8.4.1"
+esmf_ver=os.getenv("esmf_ver") or "8.4.2"
load(pathJoin("esmf", esmf_ver))
nco_ver=os.getenv("nco_ver") or "5.0.6"
diff --git a/modulefiles/build.jet.intel.lua b/modulefiles/build.jet.intel.lua
index e6ce6a54a..106d8c9b3 100644
--- a/modulefiles/build.jet.intel.lua
+++ b/modulefiles/build.jet.intel.lua
@@ -1,64 +1,64 @@
help([[
-Load environment to compile UFS_UTILS on Jet
+Load environment to compile UFS_UTILS on Jet using Intel
]])
-cmake_ver=os.getenv("cmake_ver") or "3.16.1"
-load(pathJoin("cmake", cmake_ver))
-
hpss_ver=os.getenv("hpss_ver") or ""
load(pathJoin("hpss", hpss_ver))
-prepend_path("MODULEPATH", "/lfs4/HFIP/hfv3gfs/role.epic/hpc-stack/libs/intel-2022.1.2/modulefiles/stack")
+prepend_path("MODULEPATH", "/mnt/lfs4/HFIP/hfv3gfs/role.epic/spack-stack/spack-stack-1.5.0/envs/unified-env/install/modulefiles/Core")
-hpc_ver=os.getenv("hpc_ver") or "1.2.0"
-load(pathJoin("hpc", hpc_ver))
+stack_intel_ver=os.getenv("stack_intel_ver") or "2021.5.0"
+load(pathJoin("stack-intel", stack_intel_ver))
-hpc_intel_ver=os.getenv("hpc_intel_ver") or "2022.1.2"
-load(pathJoin("hpc-intel", hpc_intel_ver))
+stack_impi_ver=os.getenv("stack_impi_ver") or "2021.5.1"
+load(pathJoin("stack-intel-oneapi-mpi", stack_impi_ver))
-impi_ver=os.getenv("impi_ver") or "2022.1.2"
-load(pathJoin("hpc-impi", impi_ver))
-
-hdf5_ver=os.getenv("hdf5_ver") or "1.10.6"
-load(pathJoin("hdf5", hdf5_ver))
+cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+load(pathJoin("cmake", cmake_ver))
-netcdf_ver=os.getenv("netcdf_ver") or "4.7.4"
-load(pathJoin("netcdf", netcdf_ver))
+bacio_ver=os.getenv("bacio_ver") or "2.4.1"
+load(pathJoin("bacio", bacio_ver))
-nccmp_ver=os.getenv("nccmp_ver") or "1.8.9.0"
-load(pathJoin("nccmp", nccmp_ver))
+g2_ver=os.getenv("g2_ver") or "3.4.5"
+load(pathJoin("g2", g2_ver))
-esmf_ver=os.getenv("esmf_ver") or "8.4.0b08"
-load(pathJoin("esmf", esmf_ver))
+ip_ver=os.getenv("ip_ver") or "4.3.0"
+load(pathJoin("ip", ip_ver))
-w3emc_ver=os.getenv("w3emc_ver") or "2.9.2"
-load(pathJoin("w3emc", w3emc_ver))
+nemsio_ver=os.getenv("nemsio_ver") or "2.5.4"
+load(pathJoin("nemsio", nemsio_ver))
sp_ver=os.getenv("sp_ver") or "2.3.3"
load(pathJoin("sp", sp_ver))
-ip_ver=os.getenv("ip_ver") or "4.0.0"
-load(pathJoin("ip", ip_ver))
+w3emc_ver=os.getenv("w3emc_ver") or "2.10.0"
+load(pathJoin("w3emc", w3emc_ver))
-bacio_ver=os.getenv("bacio_ver") or "2.4.1"
-load(pathJoin("bacio", bacio_ver))
+sfcio_ver=os.getenv("sfcio_ver") or "1.4.1"
+load(pathJoin("sfcio", sfcio_ver))
sigio_ver=os.getenv("sigio_ver") or "2.3.2"
load(pathJoin("sigio", sigio_ver))
-sfcio_ver=os.getenv("sfcio_ver") or "1.4.1"
-load(pathJoin("sfcio", sfcio_ver))
+zlib_ver=os.getenv("zlib_ver") or "1.2.13"
+load(pathJoin("zlib", zlib_ver))
-nemsio_ver=os.getenv("nemsio_ver") or "2.5.4"
-load(pathJoin("nemsio", nemsio_ver))
+png_ver=os.getenv("png_ver") or "1.6.37"
+load(pathJoin("libpng", png_ver))
-g2_ver=os.getenv("g2_ver") or "3.4.5"
-load(pathJoin("g2", g2_ver))
+netcdf_c_ver=os.getenv("netcdf_c_ver") or "4.9.2"
+load(pathJoin("netcdf-c", netcdf_c_ver))
+
+netcdf_fortran_ver=os.getenv("netcdf_fortran_ver") or "4.6.0"
+load(pathJoin("netcdf-fortran", netcdf_fortran_ver))
-prod_util_ver=os.getenv("prod_util_ver") or "1.2.2"
-load(pathJoin("prod_util", prod_util_ver))
+nccmp_ver=os.getenv("nccmp_ver") or "1.9.0.1"
+load(pathJoin("nccmp", nccmp_ver))
+
+esmf_ver=os.getenv("esmf_ver") or "8.4.2"
+load(pathJoin("esmf", esmf_ver))
-nco_ver=os.getenv("nco_ver") or "4.9.3"
+nco_ver=os.getenv("nco_ver") or "5.0.6"
load(pathJoin("nco", nco_ver))
whatis("Description: UFS_UTILS build environment")
diff --git a/modulefiles/build.orion.intel.lua b/modulefiles/build.orion.intel.lua
index 18fe99840..c7f8a5cae 100644
--- a/modulefiles/build.orion.intel.lua
+++ b/modulefiles/build.orion.intel.lua
@@ -1,20 +1,17 @@
help([[
-Load environment to compile UFS_UTILS on Orion
+Load environment to compile UFS_UTILS on Orion using Intel
]])
-cmake_ver=os.getenv("cmake_ver") or "3.22.1"
-load(pathJoin("cmake", cmake_ver))
-
-prepend_path("MODULEPATH", "/work/noaa/epic-ps/role-epic-ps/hpc-stack/libs/intel-2022.1.2_ncdf492/modulefiles/stack")
+prepend_path("MODULEPATH", "/work/noaa/epic/role-epic/spack-stack/orion/spack-stack-1.5.0/envs/unified-env/install/modulefiles/Core")
-hpc_ver=os.getenv("hpc_ver") or "1.2.0"
-load(pathJoin("hpc", hpc_ver))
+stack_intel_ver=os.getenv("stack_intel_ver") or "2022.0.2"
+load(pathJoin("stack-intel", stack_intel_ver))
-hpc_intel_ver=os.getenv("hpc_intel_ver") or "2022.1.2"
-load(pathJoin("hpc-intel", hpc_intel_ver))
+stack_impi_ver=os.getenv("stack_impi_ver") or "2021.5.1"
+load(pathJoin("stack-intel-oneapi-mpi", stack_impi_ver))
-hpc_impi_ver=os.getenv("hpc_impi_ver") or "2022.1.2"
-load(pathJoin("hpc-impi", hpc_impi_ver))
+cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+load(pathJoin("cmake", cmake_ver))
bacio_ver=os.getenv("bacio_ver") or "2.4.1"
load(pathJoin("bacio", bacio_ver))
@@ -22,7 +19,7 @@ load(pathJoin("bacio", bacio_ver))
g2_ver=os.getenv("g2_ver") or "3.4.5"
load(pathJoin("g2", g2_ver))
-ip_ver=os.getenv("ip_ver") or "4.0.0"
+ip_ver=os.getenv("ip_ver") or "4.3.0"
load(pathJoin("ip", ip_ver))
nemsio_ver=os.getenv("nemsio_ver") or "2.5.4"
@@ -31,7 +28,7 @@ load(pathJoin("nemsio", nemsio_ver))
sp_ver=os.getenv("sp_ver") or "2.3.3"
load(pathJoin("sp", sp_ver))
-w3emc_ver=os.getenv("w3emc_ver") or "2.9.2"
+w3emc_ver=os.getenv("w3emc_ver") or "2.10.0"
load(pathJoin("w3emc", w3emc_ver))
sfcio_ver=os.getenv("sfcio_ver") or "1.4.1"
@@ -40,16 +37,19 @@ load(pathJoin("sfcio", sfcio_ver))
sigio_ver=os.getenv("sigio_ver") or "2.3.2"
load(pathJoin("sigio", sigio_ver))
-zlib_ver=os.getenv("zlib_ver") or "1.2.11"
+zlib_ver=os.getenv("zlib_ver") or "1.2.13"
load(pathJoin("zlib", zlib_ver))
-hdf5_ver=os.getenv("hdf5_ver") or "1.14.0"
-load(pathJoin("hdf5", hdf5_ver))
+png_ver=os.getenv("png_ver") or "1.6.37"
+load(pathJoin("libpng", png_ver))
+
+netcdf_c_ver=os.getenv("netcdf_c_ver") or "4.9.2"
+load(pathJoin("netcdf-c", netcdf_c_ver))
-netcdf_ver=os.getenv("netcdf_ver") or "4.9.2"
-load(pathJoin("netcdf", netcdf_ver))
+netcdf_fortran_ver=os.getenv("netcdf_fortran_ver") or "4.6.0"
+load(pathJoin("netcdf-fortran", netcdf_fortran_ver))
-nccmp_ver=os.getenv("nccmp_ver") or "1.8.9.0"
+nccmp_ver=os.getenv("nccmp_ver") or "1.9.0.1"
load(pathJoin("nccmp", nccmp_ver))
esmf_ver=os.getenv("esmf_ver") or "8.4.2"
diff --git a/reg_tests/chgres_cube/driver.orion.sh b/reg_tests/chgres_cube/driver.orion.sh
index 66de8b85b..011dd0fba 100755
--- a/reg_tests/chgres_cube/driver.orion.sh
+++ b/reg_tests/chgres_cube/driver.orion.sh
@@ -102,7 +102,7 @@ TEST3=$(sbatch --parsable --ntasks-per-node=6 --nodes=1 --mem=75G -t 0:15:00 -A
LOG_FILE4=${LOG_FILE}04
export OMP_NUM_THREADS=6 # needs to match cpus-per-task
-TEST4=$(sbatch --parsable --ntasks-per-node=3 --cpus-per-task=6 --nodes=2 --mem=50G -t 0:15:00 -A $PROJECT_CODE -q $QUEUE -J c96.gfs.sigio \
+TEST4=$(sbatch --parsable --ntasks-per-node=3 --cpus-per-task=6 --nodes=2 --mem=75G -t 0:20:00 -A $PROJECT_CODE -q $QUEUE -J c96.gfs.sigio \
--open-mode=append -o $LOG_FILE4 -e $LOG_FILE4 ./c96.gfs.sigio.sh)
#-----------------------------------------------------------------------------
diff --git a/reg_tests/cpld_gridgen/rt.sh b/reg_tests/cpld_gridgen/rt.sh
index 49f353963..2b5614a92 100755
--- a/reg_tests/cpld_gridgen/rt.sh
+++ b/reg_tests/cpld_gridgen/rt.sh
@@ -108,7 +108,7 @@ TESTS_FILE="$PATHRT/rt.conf"
export TEST_NAME=
# for C3072 on hera, use WLCLK=60 and MEM="--exclusive"
-WLCLK_dflt=15
+WLCLK_dflt=20
export WLCLK=$WLCLK_dflt
MEM_dflt="--mem=12g"
export MEM=$MEM_dflt
diff --git a/util/gdas_init/driver.jet.sh b/util/gdas_init/driver.jet.sh
index 3df8cd64c..cc123c154 100755
--- a/util/gdas_init/driver.jet.sh
+++ b/util/gdas_init/driver.jet.sh
@@ -20,6 +20,9 @@ PROJECT_CODE=hfv3gfs
QUEUE=batch
PARTITION=xjet
+# Needed for NDATE utility
+module load prod_util/1.2.2
+
source config
if [ $EXTRACT_DATA == yes ]; then
From 2f8675fc85262e9dda77208ae89e6e486a39dbf5 Mon Sep 17 00:00:00 2001
From: Dom Heinzeller
Date: Fri, 17 Nov 2023 11:44:59 -0700
Subject: [PATCH 3/3] Update chgres_cube file open statement (#870)
Add "action='read'" to a Fortran open statement in atmosphere.F90.
Fixes bug described in #869.
---
sorc/chgres_cube.fd/atmosphere.F90 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sorc/chgres_cube.fd/atmosphere.F90 b/sorc/chgres_cube.fd/atmosphere.F90
index c13e709b6..cccee336f 100644
--- a/sorc/chgres_cube.fd/atmosphere.F90
+++ b/sorc/chgres_cube.fd/atmosphere.F90
@@ -1260,7 +1260,7 @@ subroutine read_vcoord_info
print*
print*,"OPEN VERTICAL COORD FILE: ", trim(vcoord_file_target_grid)
- open(14, file=trim(vcoord_file_target_grid), form='formatted', iostat=istat)
+ open(14, file=trim(vcoord_file_target_grid), form='formatted', iostat=istat, action='read')
if (istat /= 0) then
call error_handler("OPENING VERTICAL COORD FILE", istat)
endif