From cb87daaced9fddd17f8370a1842d7e4ddab24e8f Mon Sep 17 00:00:00 2001 From: DavidBurrows-NCO <82525974+DavidBurrows-NCO@users.noreply.github.com> Date: Thu, 2 May 2024 15:30:53 -0400 Subject: [PATCH 1/2] Update gfs_utils for Gaea (#2556) What: add build capability to the gfs_utils submod within the global workflow on Gaea Refs #2535 Co-authored-by: Rahul Mahajan --- sorc/gfs_utils.fd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorc/gfs_utils.fd b/sorc/gfs_utils.fd index d77c3c99a3..0cdc279526 160000 --- a/sorc/gfs_utils.fd +++ b/sorc/gfs_utils.fd @@ -1 +1 @@ -Subproject commit d77c3c99a3bc6e993c38b8ea987ceb4e68c11ebb +Subproject commit 0cdc2795260fc1b59e86a873729433a470794a97 From a005244bbfb2f1c525bca60d966f8095aa1acb8e Mon Sep 17 00:00:00 2001 From: Guoqing Ge Date: Thu, 2 May 2024 20:32:53 -0600 Subject: [PATCH 2/2] Add nest capability (#2545) This PR adds the global nesting capability to the global workflow so that one can run a regional domain nested in a global run. Resolves #2544 Co-authored-by: Rahul Mahajan --- parm/config/gefs/config.base | 7 + parm/config/gfs/config.base | 7 + parm/config/gfs/config.fcst | 3 + parm/config/gfs/config.resources | 7 + parm/config/gfs/config.stage_ic | 4 + parm/config/gfs/config.ufs | 235 +++++--- scripts/exglobal_stage_ic.sh | 13 +- sorc/link_workflow.sh | 2 +- ush/forecast_postdet.sh | 13 +- ush/forecast_predet.sh | 19 +- ush/parsing_model_configure_FV3.sh | 8 +- ush/parsing_namelists_FV3_nest.sh | 832 +++++++++++++++++++++++++++++ ush/python/pygfs/task/analysis.py | 1 - 13 files changed, 1075 insertions(+), 76 deletions(-) create mode 100755 ush/parsing_namelists_FV3_nest.sh diff --git a/parm/config/gefs/config.base b/parm/config/gefs/config.base index 07664f15ff..bc37c5abbc 100644 --- a/parm/config/gefs/config.base +++ b/parm/config/gefs/config.base @@ -137,6 +137,13 @@ export DO_AERO="NO" export WAVE_CDUMP="" # When to include wave suite: gdas, gfs, or both export DOBNDPNT_WAVE="NO" # The GEFS buoys file does not currently have any boundary points export FRAC_GRID=".true." +export DO_NEST="NO" # Whether to run a global-nested domain +if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + export ntiles=7 + export NEST_OUTPUT_GRID="regional_latlon" +else + export ntiles=6 +fi # Set operational resolution export OPS_RES="C768" # Do not change diff --git a/parm/config/gfs/config.base b/parm/config/gfs/config.base index 5a58c75220..ab35f717cb 100644 --- a/parm/config/gfs/config.base +++ b/parm/config/gfs/config.base @@ -184,6 +184,13 @@ export DO_AERO="NO" export WAVE_CDUMP="" # When to include wave suite: gdas, gfs, or both export DOBNDPNT_WAVE="NO" export FRAC_GRID=".true." +export DO_NEST="NO" # Whether to run a global-nested domain +if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + export ntiles=7 + export NEST_OUTPUT_GRID="regional_latlon" +else + export ntiles=6 +fi # Set operational resolution export OPS_RES="C768" # Do not change # TODO: Why is this needed and where is it used? diff --git a/parm/config/gfs/config.fcst b/parm/config/gfs/config.fcst index 14621307f5..63273e0fe4 100644 --- a/parm/config/gfs/config.fcst +++ b/parm/config/gfs/config.fcst @@ -254,6 +254,9 @@ export DO_SKEB=${DO_SKEB:-"NO"} export DO_SHUM=${DO_SHUM:-"NO"} export DO_LAND_PERT=${DO_LAND_PERT:-"NO"} export DO_CA=${DO_CA:-"YES"} +if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + export DO_CA="NO" # CA does not work with nesting. +fi #coupling settings export cplmode="ufs.frac" diff --git a/parm/config/gfs/config.resources b/parm/config/gfs/config.resources index aafe7b0967..89953c7b84 100644 --- a/parm/config/gfs/config.resources +++ b/parm/config/gfs/config.resources @@ -606,6 +606,13 @@ case ${step} in [[ "${DO_ICE}" == "YES" ]] && nthreads_cice6=1 fi + if (( ntiles > 6 )); then + export layout_x_nest=${layout_x_nest:-10} + export layout_y_nest=${layout_y_nest:-10} + export npx_nest=${npx_nest:-1441} + export npy_nest=${npy_nest:-961} + fi + # PETS for the atmosphere dycore (( FV3PETS = ntasks_fv3 * nthreads_fv3 )) echo "FV3 using (nthreads, PETS) = (${nthreads_fv3}, ${FV3PETS})" diff --git a/parm/config/gfs/config.stage_ic b/parm/config/gfs/config.stage_ic index 63d0e4a5cf..9956e8af6a 100644 --- a/parm/config/gfs/config.stage_ic +++ b/parm/config/gfs/config.stage_ic @@ -38,4 +38,8 @@ case "${CASE}" in ;; esac +if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + export CPL_ATMIC="GLOBAL-NEST_${CASE}" +fi + echo "END: config.stage_ic" diff --git a/parm/config/gfs/config.ufs b/parm/config/gfs/config.ufs index 7cec5a0822..e37e46cf70 100644 --- a/parm/config/gfs/config.ufs +++ b/parm/config/gfs/config.ufs @@ -68,6 +68,22 @@ if [[ "${skip_mom6}" == "false" ]] || [[ "${skip_cice6}" == "false" ]] || [[ "${ skip_mediator=false fi +if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + # Describe nest location, interaction with parent, etc. + export grid_type=0 + export stretch_fac=1.0001 + export TARGET_LAT=32.5 + export TARGET_LON=-135.0 + export NEST_LON1=-195.000000 + export NEST_LAT1=-7.500000 + export NEST_LON2=-75.000000 + export NEST_LAT2=72.500000 + export twowaynest=${twowaynest:-.true.} +else + # No nest. + export grid_type=-1 +fi + # (Standard) Model resolution dependent variables case "${fv3_res}" in "C48") @@ -89,76 +105,158 @@ case "${fv3_res}" in export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=1 ;; "C96") - export DELTIM=600 - export layout_x=2 - export layout_y=2 - export layout_x_gfs=2 - export layout_y_gfs=2 - export nthreads_fv3=1 - export nthreads_fv3_gfs=1 - export nthreads_ufs=1 - export nthreads_ufs_gfs=1 - export cdmbgwd="0.14,1.8,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling - export cdmbgwd_gsl="20.0,2.5,1.0,1.0" # settings for GSL drag suite - export knob_ugwp_tauamp=3.0e-3 # setting for UGWPv1 non-stationary GWD - export WRITE_GROUP=1 - export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=1 - export WRITE_GROUP_GFS=1 - export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=1 + if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + export DELTIM=450 + export layout_x_gfs=4 + export layout_y_gfs=4 + export layout_x_nest=12 + export layout_y_nest=10 + export nest_refine=4 + export nest_ioffset=4 + export nest_joffset=9 + export npx_nest=361 + export npy_nest=241 + export NEST_DLON=0.25 + export NEST_DLAT=0.25 + export WRITE_GROUP=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=2 + export WRITE_GROUP_GFS=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=2 + else + export DELTIM=600 + export layout_x=2 + export layout_y=2 + export layout_x_gfs=2 + export layout_y_gfs=2 + export nthreads_fv3=1 + export nthreads_fv3_gfs=1 + export nthreads_ufs=1 + export nthreads_ufs_gfs=1 + export cdmbgwd="0.14,1.8,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export cdmbgwd_gsl="20.0,2.5,1.0,1.0" # settings for GSL drag suite + export knob_ugwp_tauamp=3.0e-3 # setting for UGWPv1 non-stationary GWD + export WRITE_GROUP=1 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=1 + export WRITE_GROUP_GFS=1 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=1 + fi ;; "C192") - export DELTIM=450 - export layout_x=4 - export layout_y=6 - export layout_x_gfs=4 - export layout_y_gfs=6 - export nthreads_fv3=1 - export nthreads_fv3_gfs=2 - export nthreads_ufs=1 - export nthreads_ufs_gfs=2 - export cdmbgwd="0.23,1.5,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling - export cdmbgwd_gsl="10.0,3.5,1.0,1.0" # settings for GSL drag suite - export knob_ugwp_tauamp=1.5e-3 # setting for UGWPv1 non-stationary GWD - export WRITE_GROUP=1 - export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 - export WRITE_GROUP_GFS=2 - export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=5 + if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + export DELTIM=225 + export layout_x_gfs=5 + export layout_y_gfs=6 + export layout_x_nest=15 + export layout_y_nest=25 + export nest_refine=4 + export nest_ioffset=7 + export nest_joffset=19 + export npx_nest=721 + export npy_nest=481 + export NEST_DLON=0.125 + export NEST_DLAT=0.125 + export WRITE_GROUP=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=15 + export WRITE_GROUP_GFS=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=15 + else + export DELTIM=450 + export layout_x=4 + export layout_y=6 + export layout_x_gfs=4 + export layout_y_gfs=6 + export nthreads_fv3=1 + export nthreads_fv3_gfs=2 + export nthreads_ufs=1 + export nthreads_ufs_gfs=2 + export cdmbgwd="0.23,1.5,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export cdmbgwd_gsl="10.0,3.5,1.0,1.0" # settings for GSL drag suite + export knob_ugwp_tauamp=1.5e-3 # setting for UGWPv1 non-stationary GWD + export WRITE_GROUP=1 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 + export WRITE_GROUP_GFS=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=5 + fi ;; "C384") - export DELTIM=300 - export layout_x=8 - export layout_y=8 - export layout_x_gfs=8 - export layout_y_gfs=8 - export nthreads_fv3=2 - export nthreads_fv3_gfs=2 - export nthreads_ufs=2 - export nthreads_ufs_gfs=2 - export cdmbgwd="1.1,0.72,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling - export cdmbgwd_gsl="5.0,5.0,1.0,1.0" # settings for GSL drag suite - export knob_ugwp_tauamp=0.8e-3 # setting for UGWPv1 non-stationary GWD - export WRITE_GROUP=4 - export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 - export WRITE_GROUP_GFS=4 - export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=10 + if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + export DELTIM=150 + export layout_x=8 + export layout_y=8 + export layout_x_gfs=8 + export layout_y_gfs=8 + export layout_x_nest=34 + export layout_y_nest=24 + export nest_refine=4 + export nest_ioffset=13 + export nest_joffset=37 + export npx_nest=1441 + export npy_nest=961 + export NEST_DLON=0.0625 + export NEST_DLAT=0.0625 + export WRITE_GROUP=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=20 + export WRITE_GROUP_GFS=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=20 + else + export DELTIM=300 + export layout_x=8 + export layout_y=8 + export layout_x_gfs=8 + export layout_y_gfs=8 + export nthreads_fv3=2 + export nthreads_fv3_gfs=2 + export nthreads_ufs=2 + export nthreads_ufs_gfs=2 + export cdmbgwd="1.1,0.72,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export cdmbgwd_gsl="5.0,5.0,1.0,1.0" # settings for GSL drag suite + export knob_ugwp_tauamp=0.8e-3 # setting for UGWPv1 non-stationary GWD + export WRITE_GROUP=4 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 + export WRITE_GROUP_GFS=4 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=10 + fi ;; "C768") - export DELTIM=150 - export layout_x=8 - export layout_y=12 - export layout_x_gfs=12 - export layout_y_gfs=16 - export nthreads_fv3=4 - export nthreads_fv3_gfs=4 - export nthreads_ufs=4 - export nthreads_ufs_gfs=4 - export cdmbgwd="4.0,0.15,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling - export cdmbgwd_gsl="2.5,7.5,1.0,1.0" # settings for GSL drag suite - export knob_ugwp_tauamp=0.5e-3 # setting for UGWPv1 non-stationary GWD - export WRITE_GROUP=2 - export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 - export WRITE_GROUP_GFS=4 - export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=20 #Note this should be 10 for WCOSS2 + if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + export DELTIM=75 + export layout_x=16 + export layout_y=10 + export layout_x_gfs=16 + export layout_y_gfs=10 + export layout_x_nest=48 + export layout_y_nest=45 + export nthreads_fv3=2 + export nthreads_fv3_gfs=2 + export nest_refine=4 + export nest_ioffset=24 + export nest_joffset=72 + export npx_nest=2881 + export npy_nest=1921 + export NEST_DLON=0.0325 + export NEST_DLAT=0.0325 + export WRITE_GROUP=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=90 + export WRITE_GROUP_GFS=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=90 + else + export DELTIM=150 + export layout_x=8 + export layout_y=12 + export layout_x_gfs=12 + export layout_y_gfs=16 + export nthreads_fv3=4 + export nthreads_fv3_gfs=4 + export nthreads_ufs=4 + export nthreads_ufs_gfs=4 + export cdmbgwd="4.0,0.15,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export cdmbgwd_gsl="2.5,7.5,1.0,1.0" # settings for GSL drag suite + export knob_ugwp_tauamp=0.5e-3 # setting for UGWPv1 non-stationary GWD + export WRITE_GROUP=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 + export WRITE_GROUP_GFS=4 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=20 #Note this should be 10 for WCOSS2 + fi ;; "C1152") export DELTIM=120 @@ -209,6 +307,9 @@ export WRTTASK_PER_GROUP_PER_THREAD_GFS (( ntasks_fv3 = layout_x * layout_y * 6 )) (( ntasks_fv3_gfs = layout_x_gfs * layout_y_gfs * 6 )) +if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + (( ntasks_fv3_gfs += layout_x_nest * layout_y_nest )) +fi export ntasks_fv3 export ntasks_fv3_gfs @@ -241,7 +342,11 @@ export cplice=".false." export cplchm=".false." export cplwav=".false." export cplwav2atm=".false." -export CCPP_SUITE="${CCPP_SUITE:-FV3_GFS_v17_p8_ugwpv1}" +if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + export CCPP_SUITE="${CCPP_SUITE:-FV3_global_nest_v1}" +else + export CCPP_SUITE="${CCPP_SUITE:-FV3_GFS_v17_p8_ugwpv1}" +fi model_list="atm" # Mediator specific settings diff --git a/scripts/exglobal_stage_ic.sh b/scripts/exglobal_stage_ic.sh index 1a15ceb465..d941fa10b4 100755 --- a/scripts/exglobal_stage_ic.sh +++ b/scripts/exglobal_stage_ic.sh @@ -42,9 +42,13 @@ for MEMDIR in "${MEMDIR_ARRAY[@]}"; do err=$((err + rc)) done for ftype in ca_data fv_core.res fv_srf_wnd.res fv_tracer.res phy_data sfc_data; do - for ((tt = 1; tt <= 6; tt++)); do + for ((tt = 1; tt <= ntiles; tt++)); do src="${BASE_CPLIC}/${CPL_ATMIC:-}/${PDY}${cyc}/${MEMDIR}/atmos/${PDY}.${cyc}0000.${ftype}.tile${tt}.nc" - tgt="${COM_ATMOS_RESTART_PREV}/${PDY}.${cyc}0000.${ftype}.tile${tt}.nc" + if (( tt > 6 )) ; then + tgt="${COM_ATMOS_RESTART_PREV}/${PDY}.${cyc}0000.${ftype}.nest0$((tt-5)).tile${tt}.nc" + else + tgt="${COM_ATMOS_RESTART_PREV}/${PDY}.${cyc}0000.${ftype}.tile${tt}.nc" + fi ${NCP} "${src}" "${tgt}" rc=$? ((rc != 0)) && error_message "${src}" "${tgt}" "${rc}" @@ -62,7 +66,7 @@ for MEMDIR in "${MEMDIR_ARRAY[@]}"; do ((rc != 0)) && error_message "${src}" "${tgt}" "${rc}" err=$((err + rc)) for ftype in gfs_data sfc_data; do - for ((tt = 1; tt <= 6; tt++)); do + for ((tt = 1; tt <= ntiles; tt++)); do src="${BASE_CPLIC}/${CPL_ATMIC:-}/${PDY}${cyc}/${MEMDIR}/atmos/${ftype}.tile${tt}.nc" tgt="${COM_ATMOS_INPUT}/${ftype}.tile${tt}.nc" ${NCP} "${src}" "${tgt}" @@ -70,6 +74,9 @@ for MEMDIR in "${MEMDIR_ARRAY[@]}"; do ((rc != 0)) && error_message "${src}" "${tgt}" "${rc}" err=$((err + rc)) done + if (( ntiles > 6 )); then + ${NLN} "${COM_ATMOS_INPUT}/${ftype}.tile7.nc" "${COM_ATMOS_INPUT}/${ftype}.nest02.tile7.nc" + fi done fi diff --git a/sorc/link_workflow.sh b/sorc/link_workflow.sh index 7106d1ed79..2a9d9d04db 100755 --- a/sorc/link_workflow.sh +++ b/sorc/link_workflow.sh @@ -178,7 +178,7 @@ done # Link these templates from ufs-weather-model cd "${HOMEgfs}/parm/ufs" || exit 1 -declare -a ufs_templates=("model_configure.IN" \ +declare -a ufs_templates=("model_configure.IN" "model_configure_nest.IN"\ "MOM_input_025.IN" "MOM_input_050.IN" "MOM_input_100.IN" "MOM_input_500.IN" \ "MOM6_data_table.IN" \ "ice_in.IN" \ diff --git a/ush/forecast_postdet.sh b/ush/forecast_postdet.sh index fd1ef9a078..8ea556055d 100755 --- a/ush/forecast_postdet.sh +++ b/ush/forecast_postdet.sh @@ -180,6 +180,10 @@ EOF if [[ "${WRITE_DOPOST}" == ".true." ]]; then ${NLN} "${COM_ATMOS_MASTER}/${RUN}.t${cyc}z.master.grb2f${FH3}" "GFSPRS.GrbF${FH2}" ${NLN} "${COM_ATMOS_MASTER}/${RUN}.t${cyc}z.sfluxgrbf${FH3}.grib2" "GFSFLX.GrbF${FH2}" + if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + ${NLN} "${COM_ATMOS_MASTER}/${RUN}.t${cyc}z.nest.grb2f${FH3}" "GFSPRS.GrbF${FH2}.nest02" + ${NLN} "${COM_ATMOS_MASTER}/${RUN}.t${cyc}z.nest.sfluxgrbf${FH3}.grib2" "GFSFLX.GrbF${FH2}.nest02" + fi fi done else # TODO: Is this even valid anymore? @@ -201,7 +205,14 @@ FV3_nml() { source "${USHgfs}/parsing_namelists_FV3.sh" source "${USHgfs}/parsing_model_configure_FV3.sh" - FV3_namelists + # Call the appropriate namelist functions + if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + source "${USHgfs}/parsing_namelists_FV3_nest.sh" + FV3_namelists_nest global + FV3_namelists_nest nest + else + FV3_namelists + fi FV3_model_configure echo "SUB ${FUNCNAME[0]}: FV3 name lists and model configure file created" diff --git a/ush/forecast_predet.sh b/ush/forecast_predet.sh index a5944d5bd2..c300067ce9 100755 --- a/ush/forecast_predet.sh +++ b/ush/forecast_predet.sh @@ -117,9 +117,6 @@ FV3_predet(){ IAUFHRS=${IAUFHRS:-0} IAU_DELTHRS=${IAU_DELTHRS:-0} - # Model config options - ntiles=6 - #------------------------------------------------------------------ # changeable parameters # dycore definitions @@ -242,9 +239,16 @@ FV3_predet(){ # Conserve total energy as heat globally consv_te=${consv_te:-1.} # range 0.-1., 1. will restore energy to orig. val. before physics + if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + consv_te=0 + k_split=${k_split:-1} + k_split_nest=${k_split_nest:-4} + else + consv_te=${consv_te:-1.} # range 0.-1., 1. will restore energy to orig. val. before physics + k_split=${k_split:-2} + fi # time step parameters in FV3 - k_split=${k_split:-2} n_split=${n_split:-5} if [[ "${MONO:0:4}" == "mono" ]]; then # monotonic options @@ -370,6 +374,13 @@ FV3_predet(){ ${NCP} "${FIXgfs}/ugwd/${CASE}/${CASE}_oro_data_ls.tile${tt}.nc" "${DATA}/INPUT/oro_data_ls.tile${tt}.nc" ${NCP} "${FIXgfs}/ugwd/${CASE}/${CASE}_oro_data_ss.tile${tt}.nc" "${DATA}/INPUT/oro_data_ss.tile${tt}.nc" done + if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + ${NLN} "${DATA}/INPUT/oro_data.tile7.nc" "${DATA}/INPUT/oro_data.nest02.tile7.nc" + ${NLN} "${DATA}/INPUT/${CASE}_grid.tile7.nc" "${DATA}/INPUT/${CASE}_grid.nest02.tile7.nc" + ${NLN} "${DATA}/INPUT/${CASE}_grid.tile7.nc" "${DATA}/INPUT/grid.nest02.tile7.nc" + ${NLN} "${DATA}/INPUT/oro_data_ls.tile7.nc" "${DATA}/INPUT/oro_data_ls.nest02.tile7.nc" + ${NLN} "${DATA}/INPUT/oro_data_ss.tile7.nc" "${DATA}/INPUT/oro_data_ss.nest02.tile7.nc" + fi # NoahMP table local noahmptablefile="${PARMgfs}/ufs/noahmptable.tbl" diff --git a/ush/parsing_model_configure_FV3.sh b/ush/parsing_model_configure_FV3.sh index 59d9fb6910..7d64ab38f9 100755 --- a/ush/parsing_model_configure_FV3.sh +++ b/ush/parsing_model_configure_FV3.sh @@ -52,7 +52,13 @@ local OUTPUT_FH=${FV3_OUTPUT_FH} local IAU_OFFSET=${IAU_OFFSET:-0} # Ensure the template exists -template="${PARMgfs}/ufs/model_configure.IN" +if [[ "${DO_NEST:-NO}" == "YES" ]] ; then + local NEST_IMO=${npx_nest} + local NEST_JMO=${npy_nest} + template="${PARMgfs}/ufs/model_configure_nest.IN" +else + template="${PARMgfs}/ufs/model_configure.IN" +fi if [[ ! -f ${template} ]]; then echo "FATAL ERROR: template '${template}' does not exist, ABORT!" exit 1 diff --git a/ush/parsing_namelists_FV3_nest.sh b/ush/parsing_namelists_FV3_nest.sh new file mode 100755 index 0000000000..2f99a1cdf5 --- /dev/null +++ b/ush/parsing_namelists_FV3_nest.sh @@ -0,0 +1,832 @@ +#! /usr/bin/env bash + +# parsing namelist of FV3, diag_table, etc. + +# Disable variable not used warnings and 'masking return value' warnings +# shellcheck disable=SC2034 +# shellcheck disable=SC2312 +FV3_namelists_nest(){ + +# First argument tells us which namelist we're writing: +# global = writing input.nml for running global with a nest +# nest = writing input_nest02.nml for running the nest +namelist_mode="${1:-global}" + +if [[ "${namelist_mode}" == "nest" ]] ; then + nml_file=input_nest02.nml + only_input_nml="YES" +else + nml_file=input.nml + only_input_nml="NO" +fi + +# setup the tables +DIAG_TABLE=${DIAG_TABLE:-${PARMgfs}/ufs/fv3/diag_table} +DIAG_TABLE_APPEND=${DIAG_TABLE_APPEND:-${PARMgfs}/ufs/fv3/diag_table_aod} +DATA_TABLE=${DATA_TABLE:-${PARMgfs}/ufs/MOM6_data_table.IN} +FIELD_TABLE=${FIELD_TABLE:-${PARMgfs}/ufs/fv3/field_table} + +# set cdmbgwd +if (( gwd_opt == 2 )) && [[ ${do_gsl_drag_ls_bl} == ".true." ]]; then + cdmbgwd=${cdmbgwd_gsl} +fi + +# ensure non-prognostic tracers are set +dnats=${dnats:-0} + +if [[ "${only_input_nml:-NO}" == "NO" ]] ; then +# build the diag_table +{ +echo "UFS_Weather_Model_Forecast" +if [[ "${DOIAU}" = "YES" ]]; then + echo "${previous_cycle:0:4} ${previous_cycle:4:2} ${previous_cycle:6:2} ${previous_cycle:8:2} 0 0" +else + echo "${current_cycle:0:4} ${current_cycle:4:2} ${current_cycle:6:2} ${current_cycle:8:2} 0 0" +fi +cat "${DIAG_TABLE}" +if [[ -n "${AERO_DIAG_TABLE:-}" ]]; then + cat "${AERO_DIAG_TABLE}" +fi +cat "${DIAG_TABLE_APPEND}" +} >> diag_table_template + +local template=diag_table_template +local SYEAR=${current_cycle:0:4} +local SMONTH=${current_cycle:4:2} +local SDAY=${current_cycle:6:2} +local CHOUR=${current_cycle:8:2} +local MOM6_OUTPUT_DIR="./MOM6_OUTPUT" + +atparse < "${template}" >> "diag_table" + + +# copy data table +${NCP} "${DATA_TABLE}" data_table + +# build field_table +if [[ -n "${AERO_FIELD_TABLE:-}" ]]; then + nrec=$(wc -l < "${FIELD_TABLE}") + prec=${nrec} + if (( dnats > 0 )); then + prec=$( grep -F -n TRACER "${FIELD_TABLE}" 2> /dev/null | tail -n "${dnats}" | head -1 | cut -d: -f1 ) + prec=${prec:-0} + prec=$(( prec > 0 ? prec - 1 : prec )) + fi + { \ + head -n "${prec}" "${FIELD_TABLE}" ; \ + cat "${AERO_FIELD_TABLE}" ; \ + tail -n $(( nrec - prec )) "${FIELD_TABLE}" ; \ + } > field_table + # add non-prognostic tracers from additional table + dnats=$(( dnats + dnats_aero )) +else + ${NCP} "${FIELD_TABLE}" field_table +fi +fi # only_input_nml + +if [[ "${namelist_mode}" == "global" ]] ; then + layout_x_here=${layout_x} + layout_y_here=${layout_y} + ntiles_here=6 + npx_here=${npx} + npy_here=${npy} + k_split_here=${k_split} +else + layout_x_here=${layout_x_nest} + layout_y_here=${layout_y_nest} + ntiles_here=1 + nested_here=.true. + twowaynest_here=${twowaynest:-.true.} + nestupdate_here=${nestupdate:-7} + npx_here=${npx_nest} + npy_here=${npy_nest} + k_split_here=${k_split_nest} +fi + +cat > "${nml_file}" <> "${nml_file}" <> "${nml_file}" <> "${nml_file}" <> "${nml_file}" << EOF + oz_phys = .false. + oz_phys_2015 = .true. +EOF + ;; + "FV3_GSD_v0") + cat >> "${nml_file}" << EOF + iovr = ${iovr:-"3"} + ltaerosol = ${ltaerosol:-".false."} + lradar = ${lradar:-".false."} + ttendlim = ${ttendlim:-0.005} + oz_phys = ${oz_phys:-".false."} + oz_phys_2015 = ${oz_phys_2015:-".true."} + lsoil_lsm = ${lsoil_lsm:-"4"} + do_mynnedmf = ${do_mynnedmf:-".false."} + do_mynnsfclay = ${do_mynnsfclay:-".false."} + icloud_bl = ${icloud_bl:-"1"} + bl_mynn_edmf = ${bl_mynn_edmf:-"1"} + bl_mynn_tkeadvect=${bl_mynn_tkeadvect:-".true."} + bl_mynn_edmf_mom=${bl_mynn_edmf_mom:-"1"} + min_lakeice = ${min_lakeice:-"0.15"} + min_seaice = ${min_seaice:-"0.15"} + use_cice_alb = ${use_cice_alb:-".false."} +EOF + ;; + FV3_GFS_v16_coupled*) + cat >> "${nml_file}" << EOF + iovr = ${iovr:-"3"} + ltaerosol = ${ltaerosol:-".false."} + lradar = ${lradar:-".false."} + ttendlim = ${ttendlim:-"0.005"} + oz_phys = ${oz_phys:-".false."} + oz_phys_2015 = ${oz_phys_2015:-".true."} + do_mynnedmf = ${do_mynnedmf:-".false."} + do_mynnsfclay = ${do_mynnsfclay:-".false."} + icloud_bl = ${icloud_bl:-"1"} + bl_mynn_edmf = ${bl_mynn_edmf:-"1"} + bl_mynn_tkeadvect = ${bl_mynn_tkeadvect:-".true."} + bl_mynn_edmf_mom = ${bl_mynn_edmf_mom:-"1"} + min_lakeice = ${min_lakeice:-"0.15"} + min_seaice = ${min_seaice:-"0.15"} +EOF + ;; + FV3_GFS_v16*) + cat >> "${nml_file}" << EOF + iovr = ${iovr:-"3"} + ltaerosol = ${ltaerosol:-".false."} + lradar = ${lradar:-".false."} + ttendlim = ${ttendlim:-"0.005"} + oz_phys = ${oz_phys:-".false."} + oz_phys_2015 = ${oz_phys_2015:-".true."} + lsoil_lsm = ${lsoil_lsm:-"4"} + do_mynnedmf = ${do_mynnedmf:-".false."} + do_mynnsfclay = ${do_mynnsfclay:-".false."} + icloud_bl = ${icloud_bl:-"1"} + bl_mynn_edmf = ${bl_mynn_edmf:-"1"} + bl_mynn_tkeadvect = ${bl_mynn_tkeadvect:-".true."} + bl_mynn_edmf_mom = ${bl_mynn_edmf_mom:-"1"} + min_lakeice = ${min_lakeice:-"0.15"} + min_seaice = ${min_seaice:-"0.15"} +EOF + ;; + FV3_GFS_v17*) + local default_dt_inner=$(( DELTIM/2 )) + cat >> "${nml_file}" << EOF + iovr = ${iovr:-"3"} + ltaerosol = ${ltaerosol:-".false."} + lradar = ${lradar:-".true."} + ttendlim = ${ttendlim:-"-999"} + dt_inner = ${dt_inner:-"${default_dt_inner}"} + sedi_semi = ${sedi_semi:-".true."} + decfl = ${decfl:-"10"} + oz_phys = ${oz_phys:-".false."} + oz_phys_2015 = ${oz_phys_2015:-".true."} + lsoil_lsm = ${lsoil_lsm:-"4"} + do_mynnedmf = ${do_mynnedmf:-".false."} + do_mynnsfclay = ${do_mynnsfclay:-".false."} + icloud_bl = ${icloud_bl:-"1"} + bl_mynn_edmf = ${bl_mynn_edmf:-"1"} + bl_mynn_tkeadvect = ${bl_mynn_tkeadvect:-".true."} + bl_mynn_edmf_mom = ${bl_mynn_edmf_mom:-"1"} + do_ugwp = ${do_ugwp:-".false."} + do_tofd = ${do_tofd:-".false."} + gwd_opt = ${gwd_opt:-"2"} + do_ugwp_v0 = ${do_ugwp_v0:-".false."} + do_ugwp_v1 = ${do_ugwp_v1:-".true."} + do_ugwp_v0_orog_only = ${do_ugwp_v0_orog_only:-".false."} + do_ugwp_v0_nst_only = ${do_ugwp_v0_nst_only:-".false."} + do_gsl_drag_ls_bl = ${do_gsl_drag_ls_bl:-".true."} + do_gsl_drag_ss = ${do_gsl_drag_ss:-".true."} + do_gsl_drag_tofd = ${do_gsl_drag_tofd:-".true."} + do_ugwp_v1_orog_only = ${do_ugwp_v1_orog_only:-".false."} + min_lakeice = ${min_lakeice:-"0.15"} + min_seaice = ${min_seaice:-"0.15"} + use_cice_alb = ${use_cice_alb:-".false."} +EOF + ;; + FV3_global_nest*) + local default_dt_inner=$(( DELTIM/2 )) + cat >> "${nml_file}" << EOF + iovr = ${iovr:-"3"} + lcnorm = ${lcnorm:-".false."} + ltaerosol = ${ltaerosol:-".false."} + lradar = ${lradar:-".true."} + ttendlim = ${ttendlim:-"-999"} + dt_inner = ${dt_inner:-"${default_dt_inner}"} + sedi_semi = ${sedi_semi:-".true."} + decfl = ${decfl:-"10"} + oz_phys = ${oz_phys:-".false."} + oz_phys_2015 = ${oz_phys_2015:-".true."} + lsoil_lsm = ${lsoil_lsm:-"4"} + do_mynnedmf = ${do_mynnedmf:-".false."} + do_mynnsfclay = ${do_mynnsfclay:-".false."} + icloud_bl = ${icloud_bl:-"1"} + bl_mynn_edmf = ${bl_mynn_edmf:-"1"} + bl_mynn_tkeadvect = ${bl_mynn_tkeadvect:-".true."} + bl_mynn_edmf_mom = ${bl_mynn_edmf_mom:-"1"} + do_ugwp = ${do_ugwp:-".false."} + do_tofd = ${do_tofd:-".false."} + gwd_opt = ${gwd_opt:-"2"} + do_ugwp_v0 = ${do_ugwp_v0:-".false."} + do_ugwp_v1 = ${do_ugwp_v1:-".true."} + do_ugwp_v0_orog_only = ${do_ugwp_v0_orog_only:-".false."} + do_ugwp_v0_nst_only = ${do_ugwp_v0_nst_only:-".false."} + do_gsl_drag_ls_bl = ${do_gsl_drag_ls_bl:-".true."} + do_gsl_drag_ss = ${do_gsl_drag_ss:-".true."} + do_gsl_drag_tofd = ${do_gsl_drag_tofd:-".true."} + do_ugwp_v1_orog_only = ${do_ugwp_v1_orog_only:-".false."} + min_lakeice = ${min_lakeice:-"0.15"} + min_seaice = ${min_seaice:-"0.15"} + use_cice_alb = ${use_cice_alb:-".false."} +EOF + ;; + *) + cat >> "${nml_file}" << EOF + iovr = ${iovr:-"3"} +EOF + ;; +esac + +cat >> "${nml_file}" <> "${nml_file}" << EOF + fscav_aero = ${fscav_aero:-'*:0.0'} +EOF +fi + +cat >> "${nml_file}" <> "${nml_file}" <> "${nml_file}" << EOF + iaufhrs = ${IAUFHRS} + iau_delthrs = ${IAU_DELTHRS} + iau_inc_files= ${IAU_INC_FILES} + iau_drymassfixer = .false. + iau_filter_increments = ${IAU_FILTER_INCREMENTS:-".false."} +EOF +fi + +if [[ ${DO_CA:-"NO"} = "YES" ]]; then + cat >> "${nml_file}" << EOF + do_ca = .true. + ca_global = ${ca_global:-".false."} + ca_sgs = ${ca_sgs:-".true."} + nca = ${nca:-"1"} + ncells = ${ncells:-"5"} + nlives = ${nlives:-"12"} + nseed = ${nseed:-"1"} + nfracseed = ${nfracseed:-"0.5"} + nthresh = ${nthresh:-"18"} + ca_trigger = ${ca_trigger:-".true."} + nspinup = ${nspinup:-"1"} + iseed_ca = ${ISEED_CA:-"12345"} +EOF +fi + +if [[ "${DO_LAND_PERT:-NO}" == "YES" ]]; then + cat >> "${nml_file}" << EOF + lndp_type = ${lndp_type:-2} + n_var_lndp = ${n_var_lndp:-0} +EOF +fi + +# Close &gfs_physics_nml section +cat >> "${nml_file}" << EOF +/ +EOF + +if [[ "${namelist_mode}" == "global" ]] ; then + cat >> "${nml_file}" << EOF +&fv_nest_nml + grid_pes = $(( layout_x * layout_y * 6 )),$(( layout_x_nest * layout_y_nest )) + tile_coarse = 0,6 + num_tile_top = 6 + p_split = 1 + nest_refine = 0,${nest_refine} + nest_ioffsets = 0,${nest_ioffset} + nest_joffsets = 0,${nest_joffset} +/ +EOF +fi + +if [[ ${knob_ugwp_version} -eq 0 ]]; then + cat >> "${nml_file}" << EOF +&cires_ugwp_nml + knob_ugwp_solver = ${knob_ugwp_solver:-2} + knob_ugwp_source = ${knob_ugwp_source:-1,1,0,0} + knob_ugwp_wvspec = ${knob_ugwp_wvspec:-1,25,25,25} + knob_ugwp_azdir = ${knob_ugwp_azdir:-2,4,4,4} + knob_ugwp_stoch = ${knob_ugwp_stoch:-0,0,0,0} + knob_ugwp_effac = ${knob_ugwp_effac:-1,1,1,1} + knob_ugwp_doaxyz = ${knob_ugwp_doaxyz:-1} + knob_ugwp_doheat = ${knob_ugwp_doheat:-1} + knob_ugwp_dokdis = ${knob_ugwp_dokdis:-1} + knob_ugwp_ndx4lh = ${knob_ugwp_ndx4lh:-1} + knob_ugwp_version = ${knob_ugwp_version:-0} + launch_level = ${launch_level:-54} +/ +EOF +fi + +if [[ ${knob_ugwp_version} -eq 1 ]]; then + cat >> "${nml_file}" << EOF +&cires_ugwp_nml + knob_ugwp_solver = ${knob_ugwp_solver:-2} + knob_ugwp_source = ${knob_ugwp_source:-1,1,0,0} + knob_ugwp_wvspec = ${knob_ugwp_wvspec:-1,25,25,25} + knob_ugwp_azdir = ${knob_ugwp_azdir:-2,4,4,4} + knob_ugwp_stoch = ${knob_ugwp_stoch:-0,0,0,0} + knob_ugwp_effac = ${knob_ugwp_effac:-1,1,1,1} + knob_ugwp_doaxyz = ${knob_ugwp_doaxyz:-1} + knob_ugwp_doheat = ${knob_ugwp_doheat:-1} + knob_ugwp_dokdis = ${knob_ugwp_dokdis:-2} + knob_ugwp_ndx4lh = ${knob_ugwp_ndx4lh:-4} + knob_ugwp_version = ${knob_ugwp_version:-1} + knob_ugwp_palaunch = ${knob_ugwp_palaunch:-275.0e2} + knob_ugwp_nslope = ${knob_ugwp_nslope:-1} + knob_ugwp_lzmax = ${knob_ugwp_lzmax:-15.750e3} + knob_ugwp_lzmin = ${knob_ugwp_lzmin:-0.75e3} + knob_ugwp_lzstar = ${knob_ugwp_lzstar:-2.0e3} + knob_ugwp_taumin = ${knob_ugwp_taumin:-0.25e-3} + knob_ugwp_tauamp = ${knob_ugwp_tauamp:-3.0e-3} + knob_ugwp_lhmet = ${knob_ugwp_lhmet:-200.0e3} + knob_ugwp_orosolv = ${knob_ugwp_orosolv:-'pss-1986'} +/ +EOF +fi + +echo "" >> "${nml_file}" + +cat >> "${nml_file}" <> "${nml_file}" <> "${nml_file}" <> "${nml_file}" +#if [ $MEMBER -gt 0 ]; then +if [[ "${DO_SPPT}" = "YES" || "${DO_SHUM}" = "YES" || "${DO_SKEB}" = "YES" || "${DO_LAND_PERT}" = "YES" ]]; then + + cat >> "${nml_file}" << EOF +&nam_stochy +EOF + + if [[ ${DO_SKEB} = "YES" ]]; then + cat >> "${nml_file}" << EOF + skeb = ${SKEB} + iseed_skeb = ${ISEED_SKEB:-${ISEED}} + skeb_tau = ${SKEB_TAU:-"-999."} + skeb_lscale = ${SKEB_LSCALE:-"-999."} + skebnorm = ${SKEBNORM:-"1"} + skeb_npass = ${SKEB_NPASS:-"30"} + skeb_vdof = ${SKEB_VDOF:-"5"} +EOF + fi + + if [[ ${DO_SHUM} = "YES" ]]; then + cat >> "${nml_file}" << EOF + shum = ${SHUM} + iseed_shum = ${ISEED_SHUM:-${ISEED}} + shum_tau = ${SHUM_TAU:-"-999."} + shum_lscale = ${SHUM_LSCALE:-"-999."} +EOF + fi + + if [[ ${DO_SPPT} = "YES" ]]; then + cat >> "${nml_file}" << EOF + sppt = ${SPPT} + iseed_sppt = ${ISEED_SPPT:-${ISEED}} + sppt_tau = ${SPPT_TAU:-"-999."} + sppt_lscale = ${SPPT_LSCALE:-"-999."} + sppt_logit = ${SPPT_LOGIT:-".true."} + sppt_sfclimit = ${SPPT_SFCLIMIT:-".true."} + use_zmtnblck = ${use_zmtnblck:-".true."} + pbl_taper = ${pbl_taper:-"0,0,0,0.125,0.25,0.5,0.75"} +EOF + fi + + if [[ "${DO_OCN_SPPT:-NO}" == "YES" ]]; then + cat >> "${nml_file}" <> "${nml_file}" <> "${nml_file}" <> "${nml_file}" <> "${nml_file}" << EOF +/ +EOF + + if [[ ${DO_LAND_PERT} = "YES" ]]; then + cat >> "${nml_file}" << EOF +&nam_sfcperts + lndp_type = ${lndp_type} + LNDP_TAU = ${LNDP_TAU} + LNDP_SCALE = ${LNDP_SCALE} + ISEED_LNDP = ${ISEED_LNDP:-${ISEED}} + lndp_var_list = ${lndp_var_list} + lndp_prt_list = ${lndp_prt_list} +/ +EOF + else + cat >> "${nml_file}" << EOF +&nam_sfcperts +/ +EOF + fi + +else + + cat >> "${nml_file}" << EOF +&nam_stochy +/ +&nam_sfcperts +/ +EOF + +fi + +# Echo out formatted ""${nml_file}"" +echo "====================================" +echo "FV3_namelists_nest(): '${nml_file}'" +cat "${nml_file}" +echo "====================================" +} diff --git a/ush/python/pygfs/task/analysis.py b/ush/python/pygfs/task/analysis.py index 078e013e7f..02011423b7 100644 --- a/ush/python/pygfs/task/analysis.py +++ b/ush/python/pygfs/task/analysis.py @@ -25,7 +25,6 @@ class Analysis(Task): def __init__(self, config: Dict[str, Any]) -> None: super().__init__(config) - self.config.ntiles = 6 # Store location of GDASApp jinja2 templates self.gdasapp_j2tmpl_dir = os.path.join(self.config.PARMgfs, 'gdas')